Insert a file path string into SQL database via C# code - c#

In SQL:
INSERT INTO [dbo].[tblFiles]
([FullFilePath]
,[LastModified])
VALUES
('P:\test\test.csv',
null)
This will store the full path in the database :)
However, I need to do this in code.
SqlConnection connection = new SqlConnection(DatabaseHelper.ConnectionString);
connection.Open();
SqlCommand command = new SqlCommand( "stpInsertFile", connection);
command.CommandType = System.Data.CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#filepath", System.Data.SqlDbType.VarChar));
command.Parameters["#filepath"].Value = article.FullFilePath;
command.Parameters.Add(new SqlParameter( "#LastModified", System.Data.SqlDbType.DateTime));
command.Parameters["#LastModified"].Value = article.LastModified;
int newArticleID = Convert.ToInt32((decimal)command.ExecuteNonQuery());
command.Dispose();
connection.Close();
connection.Dispose();
return newArticleID;
With this all I get is 'P' in the full path column.
So I tried using LINQ and got the same result.
public int InsertArticleUsingLINQ(tblFile article) {
DataClassesDataContext context = new DataClassesDataContext();
tblFile newFileEntry = new tblFile();
newFileEntry.FullFilePath = article.FullFilePath;
newFileEntry.LastModified = article.LastModified;
context.tblFiles.InsertOnSubmit(newFileEntry);
context.SubmitChanges();
return newFileEntry.ID;
}
I'm not doing anything with the string before passing it to the database insert functions. I read that you need to escape the backslash but it seems to be escaping on the quote. Also read that you need an # symbol before the sql but how do you add this to a parameter?

warning: since you didn't share the stored procedure code this is just a wild guess.
did you set the size of the #filePath parameter in the definition of your stored procedure?
if you declare it as:
create procedure stpInsertFile
#filepath varchar,
#LastModified datetime
as
...
then you parameter is created as varchar(1) because of the default behaviour of varchar datatype and that would produce the result you get.please check reference documentation for char and varchar datatype on ms website.

if stpInsertFile is a Stored Procedure you will have to set in your code:
...
command.CommandType = CommandType.StoredProcedure;
else you have to set the query string in your command:
SqlCommand command = new SqlCommand( "INSERT INTO [dbo].[tblFiles] ([FullFilePath] [LastModified]) VALUES (#filepath,#LastModified)", connection);
...

Of the above options, the ADO code did not copy the full path, even with manually adding quotes. All I ever got was one character in the database.
On further inspection, the parameter was of type Varchar(1) !!! I changed this to Varchar(255) an it worked.
Note, the LINQ to SQL function did insert the full path as this was not using the Stored Procedure.
Apologies for the mistake.

Related

Procedure or function expects parameter, which was not supplied but the parameter is supplied [duplicate]

I have a stored procedure that has a parameter called UserName and in my code behind I have a SqlCommand object that I add the parameters to with the Add method. But for some reason when the command object tries to run the ExecuteReader method, it throws an exception. I am totally at a loss and have no idea why it's not recognizing the parameter. Before the ExecuteReader method is run I have a break point set so I can confirm the command object does contain the parameters being set, which is true. I know the stored procedure does return the correct data when the parameters are not added to the command object, but are hard coded in the actual stored procedure. Below is the exception message that is given in the catch block. I will also paste my code and first part of stored procedure. I would greatly appreciate any help in this issue, seeing that I have tried many different approaches to no avail. Thanks in advance.
Exception Message
Procedure or function 'someStoredProcedure' expects parameter '#UserName', which was not supplied.
Code Behind
private DataTable GetLossMitData(string code, DateTime? start, DateTime? end)
{
DataTable results = new DataTable();
string connectionString = ConfigurationManager.ConnectionStrings["asdf"].ConnectionString;
string userName = String.Empty;
try
{
using (SPSite site = new SPSite(ConfigurationManager.AppSettings["someName"]))
{
using (SPWeb web = site.OpenWeb())
{
userName = web.CurrentUser.Email.ToString();
}
}
using (SqlConnection connection1 = new SqlConnection(connectionString))
{
connection1.Open();
using (SqlCommand command1 = new SqlCommand("someStoredProcedure", connection1))
{
command1.Parameters.Add(new SqlParameter("#UserName", userName));
command1.Parameters.Add(new SqlParameter("#ProductCode", code));
SqlDataReader dr = command1.ExecuteReader(CommandBehavior.CloseConnection);
results.Load(dr);
}
connection1.Close();
}
}
catch (Exception ex)
{
}
return results;
}
Stored Procedure
#UserName nvarchar(256),
#ProductCode nvarchar(256),
#StartDate nvarchar(256) = '1/1/1900',
#EndDate nvarchar(256) = '12/30/2012'
AS
BEGIN
SET NOCOUNT ON;
Declare #UserID int
Select #UserID = Users.UserID
from Users
where Users.Email = #UserName
Try making sure that the command type is set to stored procedure.
mycommand.CommandType = System.Data.CommandType.StoredProcedure;
You will get this exception if the value of your 'userName' variable is null
If null is valid, then pass 'DBNull.Value' to the db instead:
command1.Parameters.Add(new SqlParameter("#UserName", (userName ?? DBNull.Value));
Command1.CommandType = System.Data.CommandType.StoredProcedure
This will force the ExecuteReader to perform the exec instead of just trying it as a flat command.
By default, the CommandText property needs to contain a complete SQL command, not just the name of the stored procedure.
You can change this by to set the SqlCommand's CommandType property to StoredProcedure.
Alternatively, you could explicitly pass the parameters, by changing the CommandText to "someStoredProcedure #UserName, #ProductCode"; this is a complete SQL statement and will work with the default CommandType of Text.
EDIT: I just tried it, and the only way to get that error message without setting CommandType to StoredProcedure (which he did not do) is if CommandText is EXEC someStoredProcedure. Passing a null parameter gives a different error.

How can I get multiple output parameters from a stored procedure in a web service in C#?

I have a web service in C#, I use it to consults from tables, but I want to create a WebMethod to call a stored procedure and get back multiples output parameters. I can execute it with output parameters, it doesn't work when I try to call it whit outputs parameters.
This is a sample, I want to get back more that 2 parameters.
Stored procedure:
CREATE OR REPLACE PROCEDURE O_CAPEREZ.GIO_SP (
VNOMBRE IN VARCHAR2,
SALUDO OUT VARCHAR2 )
AS
BEGIN
INSERT INTO G_PRUEBA_SP(NOMBRE)
VALUES (vNOMBRE);
SALUDO:= ('Hello: ' || vNOMBRE);
END;
And this is my code in the web service, when I execute it using output variables I get this error
[HYC00] [Oracle][ODBC]Optional feature not implemented
C# code:
[WebMethod]
public string AP_Data(string curp)
{
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (OdbcConnection con = new OdbcConnection(constr))
{
OdbcCommand cmd = new OdbcCommand("{CALL GIO_SP(?,?)}", con);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#vNOMBRE", (curp));
cmd.Parameters.Add("#vNOMBRE", OdbcType.VarChar, 18);
cmd.Connection.Open();
cmd.ExecuteNonQuery();
cmd.Parameters["#SALUDO"].Direction = ParameterDirection.ReturnValue;
cmd.Connection.Close();
string ret = Convert.ToString(cmd.Parameters["#SALUDO"].Value);
return ret;
}
}
You have to add the parameter to the list even if you're not going to set a value there:
cmd.Parameters.Add("#SALUDO", OdbcType.VarChar, 18).Direction = ParameterDirection.Output;
I don't know the the Oracle flavor is different, but in SQL I use ParameterDirection.ReturnValue rather than ParameterDirection.Output.
here's how i do it in MS SQL server 2008 But notice the data type and the lenth of the variables your create must be the same in your table
the stored proc create code
USE DATABASE DATABASE_NAME
GO
CREATE PROC SP_METHOD
#ID_CATIGORY INT,
#NAME VARCHAR (50),
#DESCRIPTION VARCHAR (50)
AS
INSERT INTO TABLE_NAME
([ID_CAT]
,[NAME_PRODUCT]
,[DESC_PRODUCT]
)
VALUES
( #ID_CATIGORY
,#NAME
,#DESCRIPTION )
GO
in the c# code
// Create SqlConnection
SqlConnection conn= new SqlConnection(#"Server=server_name;
DataBase=your_data_base_name;Integrated Security=false;User
Id=user_id;Password=password");
// Open the Connection
if (sqlconnection.State != ConnectionState.Open)
{
conn= .Open();
}
// execute stored_procedure method don't change this
public void ExecuteCommand(string stored_procedure, SqlParameter[] param)
{
SqlCommand sqlcomd = new SqlCommand();
sqlcomd.CommandType = CommandType.StoredProcedure;
sqlcomd.CommandText = stored_procedure;
sqlcomd.Connection = sqlconnection;
if (param !=null)
{
sqlcomd.Parameters.AddRange(param);
}
sqlcomd.ExecuteNonQuery();
}
// close connection method
public void close_conn()
{
if (sqlconnection.State == ConnectionState.Open)
{
sqlconnection.Close();
}
}
// execute and retrieving data Method
public void Add_product(int ID_cat ,string Name_Product,string
Des_Product)
{
SqlParameter[] param = new SqlParameter[3];
param[0] = new SqlParameter("#ID_CAT", SqlDbType.Int);
param[0].Value = ID_cat;
param[1] = new SqlParameter("#NAME_PRODUCT", SqlDbType.VarChar, 50);
param[1].Value = Name_Product;
param[2] = new SqlParameter("#DESC_PRODUCT", SqlDbType.VarChar, 50);
param[2].Value = Des_Product;
ExecuteCommand("StoredProcedure_name", param);
close_conn();
}
and finally you can call this function
Add_product(Convert.ToInt32(ComboBox.SelectedValue),txt_name.Text,
txt_desc.Text);
if there is any part you don't understand lemme know
I've seen many ways to accomplish this.
One way is to Pipe Delimit your select statement in your stored procedure and then use "Value1|Value2".Split('|')[0] to get Value1.
You could also return a table instead of using multiple parameters
DataTable table = new DataTable();
DataAdapter adapter = new DataAdapter(cmd);
adapter.fill(table);
return table.Rows[0]["Greeting"] + table.Rows[0]["Name"];
In the second example you can return as many 'Parameters' as you want, but you will have to assign them to their rightful spots later in your code.
I've also seen an XML way to do this same feature but I won't provide the code here since I don't personally think it is a very good way to do it. The way I've seen done was adding a bunch of XML attributes to a parent tag, and then coming back later and finding the value of each tag later in the code.
In MYSQL it would go like this
CREATE PROCEDURE O_CAPEREZ.GIO_SP (
#vNOMBRE VARCHAR(50))
AS
BEGIN
INSERT INTO G_PRUEBA_SP(NOMBRE)
VALUES (#vNOMBRE);
select 'Hola' as Greeting, #vNOMBRE as Name
END
Also note what Marc_s commented
You need to set the .Direction of the parameter BEFORE making the call to .ExecuteNonQuery()

Using SQL parameters to DROP INDEX in C#

I'm trying to follow best practice (and also remove Visual Studio Code Analysis warnings) by using parameters when dropping a SQL Server index.
Not using parameters works fine:
string tableName = "dbo.TableName";
SqlCommand sqlCommand = new SqlCommand("DROP INDEX Blah ON " + tableName);
sqlCommand.Connection = sqlConnection;
sqlCommand.ExecuteNonQuery();
However, when I try to use a parameter I get an error
Incorrect syntax near '#TableName'.
Code:
string tableName = "dbo.TableName";
SqlCommand sqlCommand = new SqlCommand("DROP INDEX Blah ON #TableName");
sqlCommand.Parameters.Add(new SqlParameter("TableName", tableName));
sqlCommand.Connection = sqlConnection;
sqlCommand.ExecuteNonQuery();
What am I doing wrong?
You are doing nothing wrong. Parameters cannot be used to replace identifiers -- column names/aliases, table names/aliases, schema names, and database names. They also cannot be used to replace function names or operators or keywords.
That is a long list. They can be used to replace constants in the query.
I guess the way to remember this is that the parameterized query can be pre-compiled. In order to compile a query, all object references need to be resolved -- so the values cannot be provided by parameters.
You have already solved the problem by putting the table in the string. You can use quotename() to help protect against injection (see here).
DROP INDEX is a DDL statement, most DDL statements don't accept parameterized values. The best you can do is use dynamically constructed SQL and escape the table name using QUOTENAME
string tableName = "dbo.TableName";
string sql = #"
declare #sql nvarchar(500)
set #sql = N'DROP INDEX Blah ON ' + QUOTENAME(#TableName)
exec sp_executesql #sql
";
SqlCommand sqlCommand = new SqlCommand("");
sqlCommand.Parameters.Add("#TableName", SqlDbType.NVarChar, 50).Value = tableName;
sqlCommand.Connection = sqlConnection;
sqlCommand.ExecuteNonQuery();
I also updated your code to use the more "normal" way to add a parameter, explicitly setting the datatype of the parameter.

Error on SQL Server Insert stored procedure

I'm trying to simply insert data into a table in SQL Server from a C# winforms application.
Currently when the executing the query I'm receiving the error:
Incorrect syntax near 'soAddItems'
Here is my insert code of the class handling my database CRUD operations:
Note: As test data:
itemName = "test"
skuNo = "a123"
itemPrice = 2.99
stockItemToAdd = 3
itemPic = "C:\Users\Name\Pictures\pic.png"**
Code:
public virtual void AddItem(string itemName, string skuNo, double itemPrice, int stockAmountToAdd, string itemPic)
{
using (SqlConnection open = new SqlConnection(connectionString))
{
SqlCommand insertCommand = new SqlCommand("soAddItems", open);
open.Open();
insertCommand.Parameters.Add("#itemName", SqlDbType.NChar).Value = itemName;
insertCommand.Parameters.Add("#skuNo", SqlDbType.VarChar).Value = skuNo;
insertCommand.Parameters.Add("#itemPrice", SqlDbType.Decimal).Value = itemPrice;
insertCommand.Parameters.Add("#instockAmount", SqlDbType.BigInt).Value = stockAmountToAdd;
insertCommand.Parameters.Add("#lastSold", SqlDbType.DateTime).Value = DateTime.Today;
insertCommand.Parameters.Add("#itemPic", SqlDbType.NChar).Value = itemPic;
//***** Error on the execute*****
insertCommand.ExecuteNonQuery();
};
}
SQL Server stored procedure:
ALTER PROC [dbo].[soAddItems]
#itemName nchar,
#skuNo varchar,
#itemPrice float,
#instockAmount bigint,
#lastSold dateTime,
#itemPic varchar
AS
BEGIN
INSERT INTO items (itemName, skuNo, itemPrice, instockAmount, lastSold, itemPic)
VALUES (#itemName, #skuNo, #itemPrice, #instockAmount, #itemPic)
END
Can anyone tell me where I'm going wrong?
You need to tell the SqlCommand command type as stored procedure.
Try this:
insertCommand.CommandType = CommandType.StoredProcedure;
It looks like you forget to assign your SqlCommand.CommandType property.
Because it is Text as a default.
insertCommand.CommandType = CommandType.StoredProcedure;
Besides the missing CommandType.StoredProcedure, you have a second major flaw: if you define a parameter like this: #skuNo varchar - then you get a string of 1 character length!
That's usually not what you want - you should ALWAYS specify a length when defining parameters and variables in T-SQL!
Use: #skuNo varchar(50) or whatever length you need

Unable to insert data to database in asp.net C#

I'm new in C# programming, so I'll appreciate if anyone can help me. I know there are similar question but I still can't find the solution for my problem. I'm developing a mock system, where when user bought the product, the system will store all the transaction details. the problem is, I cannot insert the data into the database. Here's the code:
using (SqlConnection conn = new SqlConnection
(ConfigurationManager.ConnectionStrings["database"].ConnectionString))
{
string QueryA = "#Insert into TransDetails(AccountNumber,Amount,Provider"
+ ",Mobile Number,TransNum,TransDate, Status) "
+ " Values (#AccountNumber,#Amount,#Provider,#Mobile Number,"
+ "#TransNum,#TransDate,#Status";
using (SqlCommand cmd = new SqlCommand("InsertRecord", conn))
{
conn.Open();
cmd.CommandType = CommandType.Text;
cmd.CommandText = QueryA;
cmd.Parameters.AddWithValue("#AccountNumber", acc.Text);
cmd.Parameters.AddWithValue("#Amount", lblAmount.Text);
cmd.Parameters.AddWithValue("#Provider", lblProvider.Text);
cmd.Parameters.AddWithValue("#Mobile Number", lblNumber.Text);
cmd.Parameters.AddWithValue("#TransNum", lblTrans.Text);
cmd.Parameters.AddWithValue("#TransDate", lblDate.Text);
cmd.Parameters.AddWithValue("#Status", status.Text);
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch
{
lblMessage.Text = "Error";
}
finally
{
conn.Close();
}
}
}
and the stores procedures are as follows:
ALTER PROCEDURE InsertRecord1
#AccountNumber int,
#Amount nchar(10),
#Provider nchar(10),
#MobileNumber int,
#TransNum nchar(10),
#TransDate date,
#Status nchar(10)
AS
Insert into TransDetails(AccountNumber,Amount,Provider,MobileNumber,TransNum,TransDate,Status)
Values (#AccountNumber,#Amount,#Provider,#MobileNumber,#TransNum,#TransDate,#Status)
return
Really appreciate any help.
P/S: i dont know why the beginning of the stored procedures started with "alter".
I may be reading it wrong, but it looks like your stored procedure is not used at all. Try commenting out "cmd.CommandText = QueryA;" and substitute "cmd.CommandText = "InsertRecord1";" and change CommandType to StoredProcedure.
QueryA, by the way, is missing a paren at the end. However, the whole thing is unnecessary since you have a stored procedure that does the same thing and it's almost always preferable to use a stored procedure rather than embedded DML.
You must escape Mobile Number while brackets
Insert into TransDetails(AccountNumber,Amount,Provider,[Mobile Number],...
and remove the space in your parameter
...,#MobileNumber,#TransNum,#TransDate,#Status
and change the paramname in your command parameter
cmd.Parameters.AddWithValue("#MobileNumber", lblNumber.Text);
but seeing your stored procedure, the column Mobile Number has no space between it. Is it a typo error in your query on QueryA? If it is, then remove the space on it (also on parameter name)
Insert into TransDetails(AccountNumber,Amount,Provider,MobileNumber,...
or
change your CommandType.Text to CommandType.StoredProcedure and remove this line,
cmd.CommandText = QueryA;
You're using the wrong overload of the SqlCommand constructor. According to MSDN:
new SqlCommand(string, SqlConnection) Initializes a new instance of the SqlCommand class with the text of the query and a SqlConnection.
What you need to do is either set your CommandType for the sql command to CommandType.StoredProcedure and not use QueryA, or initialize the sql command with QueryA and not make use of your stored procedure.
As you can see there is # at the start of your SQL Statement.
Also you are not really using the Store Procedure.
You can Try this:
using (SqlConnection conn = new SqlConnection (ConfigurationManager.ConnectionStrings["database"].ConnectionString))
{
conn.Open();
SqlCommand cmd = new SqlCommand("InsertRecord1", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#AccountNumber", acc.Text);
cmd.Parameters.AddWithValue("#Amount", lblAmount.Text);
cmd.Parameters.AddWithValue("#Provider", lblProvider.Text);
cmd.Parameters.AddWithValue("#Mobile Number", lblNumber.Text);
cmd.Parameters.AddWithValue("#TransNum", lblTrans.Text);
cmd.Parameters.AddWithValue("#TransDate", lblDate.Text);
cmd.Parameters.AddWithValue("#Status", status.Text);
try
{
cmd.ExecuteNonQuery();
}
catch
{
lblMessage.Text = "Error";
}
finally
{
conn.Close();
}
}
Tho I don't use SQL Commands, Adapters...etc. to access the data from the SQL Database. I prefer Microsoft Data Access ApplicationBlocks which is easy-to-use library provided by Microsoft to access data from SQL Server.
Download
You can download it here http://download.microsoft.com/download/VisualStudioNET/daabref/RTM/NT5/EN-US/DataAccessApplicationBlock.msi
Introduction
https://web.archive.org/web/20210304123854/https://www.4guysfromrolla.com/articles/062503-1.aspx

Categories

Resources