I want to run an insert query in C#, which has multiple parameters. I just want to have a for loop, so that it goes through all parameters and assign a value to that parameter.
Query is in access database.
public static bool SubmitData(string queryName)
{
OleDbConnection conn = new OleDbConnection(cnnString);
OleDbCommand cmd = new OleDbCommand(queryName, conn);
OleDbDataAdapter da = new OleDbDataAdapter();
DataSet ds = new DataSet();
string strParameterName;
conn.Open();
cmd = new OleDbCommand(queryName, conn);
cmd.Connection = conn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = queryName;
for (int i = 0; i < cmd.Parameters.Count; i++)
{
}
conn = null;
return true;
}
Above example has 3 parameters, but count is coming up as 0.
I really fail to see where are the three parameters. Parameters.Count does not return the number of parameters your procedure receiver. It returns the count for the already added parameters.
What you probably want is:
cmd.Parameters.Add("#p1", OleDbType.Type1).Value = value1;
cmd.Parameters.Add("#p2", OleDbType.Type2).Value = value2;
Parameters is the parameter collection, initially empty. The method Add, add the parameter, and the Value property assign it's value.
Note that in OleDbConnection, the order of the parameter matters, so you need to know before hand the order from the query.
Related
In sql I normally execute my procedure using
exec dbo.usp_FCS 'TIMV','serial'
And I tried something somewhat the same in c# but it seems I got this wrong
using (SqlConnection connection = new SqlConnection("Data Source=;Initial Catalog=;User ID=;Password="))
{
using (SqlCommand cmd = new SqlCommand("usp_FCS_GetUnitInfo_Takaya" + "'" + MachineName + " ','serial' " , connection))
{
try
{
connection.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
}
catch (SqlException ex)
{
label6.Visible = true;
label6.Text = string.Format("Failed to Access Database!\r\n\r\nError: {0}", ex.Message);
return;
}
}
}
My question is,how can I give those 2 inputs 'TIMV' and 'serial' of my stored procedure using c#?
Edit:
I tried something like this:
using (SqlCommand cmd = new SqlCommand("usp_FCS_GetUnitInfo_Takaya" , connection))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#p1", SqlDbType.VarChar).Value = MachineName;
cmd.Parameters.Add("#p2", SqlDbType.VarChar).Value = "serial";
try
{ my code...
And it is still not working
The most correct way to add a parameter to an SqlCommand is through the Add method that allows you to specify the datatype of the parameter and, in case of strings and decimals, the size and the precision of these values. In that way the Database Engine Optimizer can store your query for reuse and be a lot faster the second time you call it. In your case I would write
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#mname", SqlDbType.NVarChar, 20).Value = MachineName;
cmd.Parameters.Add("#serial", SqlDbType.NVarChar, 20).Value = "serial";
This assumes that your stored procedure receives two parameters named EXACTLY #mname and #serial, the type of the parameters is NVarChar and the length expected is 20 char. To give a more precise answer we need to see at least the first lines of the sp.
In your code above also the execution of the command is missing. Just creating the command does nothing until you execute it. Given the presence of an SqlDataAdapter I think you want to fill a DataSet or a DataTable and use this object as DataSource of your grid. Something like this
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
yourDataGrid.DataSource = dt;
And if this is an ASP.NET app, also the DataBind call
yourDataGrid.DataBind();
You use the Parameters collection of the SqlCommand class to send parameters to a stored procedure.
Suppose your parameter names are #p1 and #p2 (Please, for your sake, don't use names like this ever) - your c# code would look like this:
using (var cmd = new SqlCommand("usp_FCS_GetUnitInfo_Takaya", connection))
{
cmd..CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#p1", SqlDbType.VarChar).Value = MachineName;
cmd.Parameters.Add("#21", SqlDbType.VarChar).Value = "serial";
try
{
// rest of your code goes here....
Note: use the SqlDbType value that fits the parameters data type.
Try this:
DataSet ds = new DataSet("dts");
using (SqlConnection conn = new SqlConnection
("Data Source=;Initial Catalog=;User ID=;Password="))
{
try
{
SqlCommand sqlComm = new SqlCommand("usp_FCS_GetUnitInfo_Takaya",conn);
sqlComm.Parameters.AddWithValue("#p1", MachineName);
sqlComm.Parameters.AddWithValue("#p2", "serial");
sqlComm.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = sqlComm;
da.Fill(ds);
}
catch (Exception e)
{
label6.Visible = true;
label6.Text = string.Format
("Failed to Access Database!\r\n\r\nError: {0}", ex.Message);
return;
}
I have the following code which does a select based upon a string field and a date and if it returns anything then it tries to do an update. The select returns something, however when I do an update the variable "affected" is set to zero, Could this be because of dates? My date variable is set to (in British format) {02/06/2016 13:10:00} when I inspect it, so it does have a time component.
// DateTime Md, string ht = these are set at this point
var conn = new OleDbConnection();
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\MyPath\\MyDb.accdb";
conn.Open();
var cmdSel = conn.CreateCommand();
cmdSel.CommandText = #"SELECT * FROM MyTable WHERE Md = #MD AND HT=#HT";
cmdSel.Parameters.AddWithValue("#MD", Md);
cmdSel.Parameters.AddWithValue("#HT", ht);
var da = new OleDbDataAdapter(cmdSel);
var ds = new DataSet();
da.Fill(ds);
if (ds.Tables[0].Rows.Count > 0)
{
var cmd = conn.CreateCommand();
cmd.CommandText = #"UPDATE MyTable SET HS=#HS WHERE Md = #MD AND HT=#HT";
cmd.Parameters.AddWithValue("#MD", Md);
cmd.Parameters.AddWithValue("#HT", ht);
cmd.Parameters.AddWithValue("#HS", hs);
var affected = cmd.ExecuteNonQuery();
}
Access/OleDB doesn't use named parameters as such, they are just positional placeholders. So, you must supply the parameter values in the exact order listed in the SQL. Your code with the other recommended fixes would be something like:
string sql = #"UPDATE MyTable SET HS=#HS WHERE Md = #MD AND HT=#HT";
using (OleDbConnection dbcon = new OleDbConnection(AceConnStr))
{
// other code
using (OleDbCommand cmd = new OleDbCommand(sql, dbcon))
{
// add in the same order as in SQL
// I have no idea that these are
cmd.Parameters.Add("#HS", OleDbType.VarChar).Value = Hs;
cmd.Parameters.Add("#MD", OleDbType.Date).Value = Md;
cmd.Parameters.Add("#HT", OleDbType.Integer).Value = Ht;
int rows = cmd.ExecuteNonQuery();
} // closes and disposes of connection and command objects
}
The results of not disposing of things which ought to be seen in this question where the user ran out of resources trying to manually insert in a loop.
You also do not need to create a DataAdapter (or DataSet) just to fill a table' you can use a DataReader to do the same thing.
myDT.Load(cmd.ExecuteReader());
In the ShippedContainerSettlement program I am trying to add parameters to a SQL statement on a stored procedure that I created on the remote server (plex).
public void checkGradedSerials()
{
localTable = "Graded_Serials";
List<string> gradedHides = new List<string>();
string queryString = "call sproc164407_2053096_650214('#startDate', '" + endDate + "');";
OdbcDataAdapter adapter = new OdbcDataAdapter();
OdbcCommand command = new OdbcCommand(queryString, connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("#startDate", startDate);
adapter.SelectCommand = command;
connection.Open();
while (rowsCollected == false)
{
if (retries <= 5)
{
try
{
DataTable table = new DataTable();
adapter.Fill(table);
An error is thrown when I use the parameter #startDate and give it a value. However, when I run the program, and add the parameters how I have done for endDate, it runs fine?
The error I get back is:
Any ideas what I am doing wrong.
EDIT:
I have incorporated some of the changes mentioned below. Here is the code I used.
public void checkGradedSerials()
{
localTable = "Graded_Serials";
List<string> gradedHides = new List<string>();
OdbcCommand command = new OdbcCommand("sproc164407_2053096_650214", odbcConnection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("#startDate", startDate);
command.Parameters.AddWithValue("#endDate", endDate);
OdbcDataAdapter adapter = new OdbcDataAdapter();
adapter.SelectCommand = command;
odbcConnection.Open();
while (rowsCollected == false)
{
if (retries <= 5)
{
try
{
DataTable table = new DataTable();
adapter.Fill(table);
But it doesn't seem to be receiving the parameters i am sending through as I am getting this error.
Here is the stored procedure I am using. This might look odd but remember this is working when I simply pass a string into a select command (see endDate in first code example above).
SELECT DISTINCT(Serial_No)
FROM Part_v_Container_Change2 AS CC
WHERE CC.Change_Date > #Change_Start_Date AND
CC.Change_Date <= #Change_End_Date AND
CC.Location = 'H Grading';
and the parameters are added here:
You should use the System.Data.SqlClient. You can explicitly declare the datatypes of paramaters you are sending... like this:
SqlConnection cn;
cn = new SqlConnection(ConnectionString);
SqlCommand cmd;
cmd = new SqlCommand("sproc164407_2053096_650214", cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#startDate", SqlDbType.DateTime);
cmd.Parameters["#startDate"].Value = startDate;
cmd.Parameters.Add("#enddate", SqlDbType.VarChar);
cmd.Parameters["#enddate"].Value = enddate;
If you must use the ODBC, then you do have to use the ODBC CALL syntax, which does not support named parameters. So change your queryString line to:
string queryString = "{call sproc164407_2053096_650214 (?, ?)}";
Then you can add your parameters:
command.Parameters.Add("#startDate", OdbcType.DateTime).Value=startDate;
command.Parameters.Add("#endDate", OdbcType.DateTime).Value=endDate;
Use SqlCommand instead of odbc.
Just put the stored proc name in the CommandText, not a SQL statement to execute it. Adding the param values means the adapter will pass in the params in the right format. You don't need to do the string manipulation in CommandText.
If you need to use OdbcCommand then see this answer showing you need to use ? syntax for the parameters, so maybe change your CommandText back to including the 'call' or 'exec' command and parameter placeholders, then make sure you AddWithValue the params in the right order
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["connecton1"].ConnectionString);
conn.Open();
SqlCommand check = new SqlCommand("SELECT Location FROM Items WHERE Serial="+Convert.ToInt32(Serialtxt.Text).ToString()+"", conn);
string checker = check.ExecuteReader();
I'm trying to look for a piece of data in my database and assign it to a variable. The error I get is
Cannot implicitly convert type 'System.Data.SqlClient.SqlDataReader' to string
What am I doing wrong?
You have to use ExecuteScalar instead.
string checker = (string)check.ExecuteScalar();
You should also use sql-parameters to prevent sql-injection.
SqlCommand check = new SqlCommand("SELECT Location FROM Items WHERE Serial = #Serial", conn);
check.Parameters.AddWithValue("#Serial", Convert.ToInt32(Serialtxt.Text));
If you instead expect multiple rows per serial you can use ExecuteReader and fill a List<string>:
List<string> allLocations = new List<string>();
using(SqlDataReader rd = check.ExecuteReader())
while(rd.Read())
allLocations.Add(rd.GetString(0));
change the checker type from string to SqlDataReader
then you could do
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["connecton1"].ConnectionString);
conn.Open();
SqlCommand check = new SqlCommand("SELECT Location FROM Items WHERE Serial ="+Convert.ToInt32(Serialtxt.Text).ToString()+"", conn);
SqlDataReader checker = check.ExecuteReader();
while (checker.Read())
{
if (checker[0] != null)
{
//some logic with the result
}
}
I have a data conduit class where I want to create an update method that takes list of parameter names, their values and a stored procedure name. Up on execution, I want to update a particular row in sql db.
The code so far in data conduit class is:
public class clsDataConduit
{
SqlConnection Conn= new SqlConnection();
SqlDataReader rdr= null;
SqlDataAdapter dataChannel = new SqlDataAdapter();
SqlCommandBuilder commandBuilder = new SqlCommandBuilder();
SqlCommand cmd = null;
List<SqlParameter> SQLParams = new List<SqlParameter>();
DataTable queryResults = new DataTable();
DataRow newRecord;
public void NewRecord(string SProcName)
{
//works fine
}
public void UpdateRecord(string SProcName)
{
Conn= new SqlConnection(connectionString);
//open the database
Conn.Open();
//initialise the command builder for this connection
SqlCommand dataCommand = new SqlCommand(SProcName, Conn);
//add the parameters to the command builder
//loop through each parameter
for (int Counter = 0; Counter < SQLParams.Count; Counter += 1)
{
//add it to the command builder
dataCommand.Parameters.Add(SQLParams[Counter]);
}
dataCommand.CommandType = CommandType.StoredProcedure;
dataChannel = new SqlDataAdapter(SProcName, Conn);
dataChannel.UpdateCommand = dataCommand;
commandBuilder = new SqlCommandBuilder(dataChannel);
dataChannel.Update(queryResults);
///////////////////////////////////////////////////////////
// Method runs fine till above code, BUT I am not too sure
// how to write the rest of the code so that It updates a
// a particular row in sql
///////////////////////////////////////////////////////////
//get the structure of a single record
//newRecord = queryResults.NewRow(); //from previous method - new data
Conn.Close();
}
}
I am not too sure how can I continue further from this point. If someone can help me out please.
Thanks
If I understand your code correctly, you have already filled the command with the appropriate parameters (with values already set), so you need only to call
dataCommand.ExecuteNonQuery();
This is all you need, (of course the SQLParams list should be already filled with the parameters and their values). Also, to be more generic, you could pass to the UpdateRecord, the list of SqlParameter to use for the storedprocedure called
public void UpdateRecord(string SProcName, List<SqlParameters> prms)
{
using(Conn= new SqlConnection(connectionString))
{
//open the database
Conn.Open();
//initialise the command builder for this connection
SqlCommand dataCommand = new SqlCommand(SProcName, Conn);
//add the parameters to the SqlCommand
dataCommand.Parameters.AddRange(prms.ToArray());
dataCommand.CommandType = CommandType.StoredProcedure;
dataCommand.ExecuteNonQuery();
}
}