Parameter "#xxx" has already been defined [closed] - c#
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I have the code below and when it enters into the ForEach loop, the error hapens.
I read this
StackOverFlow
But didnt made it =\ I need to know what do I have to change. I tryed to move the MySqlCommand, but didnt solve the problem... Thanks
I had 3 different methods (Select,Insert,Update) But i had to use "Transaction" So I puted the 3 methods at the same... First time it works fine, but the second loop throught the error happens in the INSERT QUERY
#region Querys
string Select = #"SELECT id_convidado, nome, cod_dependente, dt_insercao, matricula FROM convidado_acesso WHERE debpag = 0 AND status <> 'Devolvido'";
string Insert = #"INSERT INTO debpag (
numero_int,
parcela,
tipo_pessoa,
matricula,
cod_dependente,
ev_financeiro,
quantidade,
valor_unitario,
valor_total,
dt_lancamento,
dt_vencimento,
dt_pagamento,
dt_insercao,
dt_insercao_pagamento,
referencia,
cobrador_lancto,
cobrador_pagto,
usr_lancto,
forma_pagto)
VALUES (
#numero_int,
#parcela,
#tipo_pessoa,
#matricula,
#cod_dependente,
#ev_financeiro,
#quantidade,
#valor_unitario,
#valor_total,
#dt_lancamento,
#dt_vencimento,
#dt_pagamento,
#dt_insercao,
#dt_insercao_pagamento,
#referencia,
#cobrador_lancto,
#cobrador_pagto,
#usr_lancto,
#forma_pagto)";
string Update = "UPDATE convidado_acesso SET dt_saida = #dt_saida, usr_saida= #usr_saida, status= #status, debpag = #deb WHERE nome = #nome AND debpag = 0";
#endregion
#region MySql
MySqlConnection conexao = conexao = new MySqlConnection("Server= localhost; Database = crdores; Uid= root;Pwd = ik9rru2j;Allow Zero Datetime = true");
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = conexao;
cmd.CommandType = CommandType.Text;
cmd.CommandText = Select;
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
conexao.Open();
ta = conexao.BeginTransaction();
#endregion
try
{
#region TratamentoSelect
List<Convidado> convidado = null;
Convidado retorno = null;
if ((ds.Tables.Count > 0) && (ds.Tables[0].Rows.Count > 0))
{
convidado = new List<Convidado>();
foreach (DataRow row in ds.Tables[0].Rows)
{
string status = "";
int deb = 0;
retorno = new Convidado();
try
{
retorno.Nome = row["nome"].ToString();
}
catch { }
try
{
retorno.Cod_Dep = Convert.ToInt32(row["cod_dependente"]);
}
catch { }
try
{
retorno.Dt_Insercao = Convert.ToDateTime(row["dt_insercao"]);
}
catch { }
try
{
retorno.Matricula = Convert.ToInt32(row["matricula"]);
}
catch { }
try
{
retorno.Id_Convidado = Convert.ToInt32(row["id_convidado"]);
}
catch { }
#region Variaveis
string tmp = BuscaTempoLimite();
int z = tmp.Length;
string h = tmp.Remove(1, z - 1);
string m = tmp.Remove(0, 2);
string saida = BuscaHoraServidor();
retorno.Dt_Insercao = retorno.Dt_Insercao.AddMinutes(15);
string entrada = retorno.Dt_Insercao.ToString("HH:mm");
DateTime insercao = Convert.ToDateTime(retorno.Dt_Insercao);
DateTime left = Convert.ToDateTime(saida);
saida = left.ToString("HH:mm");
int horaEntrada = Convert.ToInt32(entrada.Remove(2, 3));
int minutosEntrada = Convert.ToInt32(entrada.Remove(0, 3));
int horaSaida = Convert.ToInt32(saida.Remove(2, 3));
int minutosSaida = Convert.ToInt32(saida.Remove(0, 3));
TimeSpan first = new TimeSpan(horaEntrada, minutosEntrada, 0);
TimeSpan last = new TimeSpan(horaSaida, minutosSaida, 0);
TimeSpan result = last - first;
TimeSpan limite = new TimeSpan(Convert.ToInt32(h), Convert.ToInt32(m), 59);
int hora = last.Hours - first.Hours;
int minutosss = last.Minutes - first.Minutes;
result = new TimeSpan(hora, minutosss, 0);
#endregion
if (left.Day <= insercao.Day)
{
if (result > limite)
{
status = "Pago";
deb = 0;
}
else
{
status = "Devolvido";
deb = 2;
}
}
else
{
status = "Pago";
}
#endregion
#region TratamentoInsert
cmd.CommandText = Insert;
#region váriaveis
int cash = 0;
string eventoF = "", usre = "", cobrador = "", tmpLimite = "";
int ide = 0;
ide = PegaMaxID();
string insercao_pagto;
string dt_lancamento = BuscaHoraServidor();
string saidaa = VerificaSaida(Convert.ToInt32(retorno.Id_Convidado));
string referencia = retorno.Dt_Insercao.ToString("MM/yyyy");
if (saida != "")
{
insercao_pagto = saida;
}
else
{
insercao_pagto = BuscaHoraServidor();
}
int tipo_pessoa;
if (retorno.Cod_Dep > 0)
{
tipo_pessoa = 3;
}
else
{
tipo_pessoa = 1;
}
retorno.Dt_Insercao = retorno.Dt_Insercao.AddHours(1);
retorno.Dt_Insercao = retorno.Dt_Insercao.AddMinutes(15);
retorno.Dt_Insercao = retorno.Dt_Insercao.AddSeconds(59);
string ent = retorno.Dt_Insercao.ToString("dd/MM/yyyy");
#endregion
DataSet confg = pag.BuscaConfigs();
foreach (DataRow roww in confg.Tables[0].Rows)
{
eventoF = roww["ev_financeiro"].ToString();
cash = Convert.ToInt32(roww["valor"]);
usre = roww["usr_insercao"].ToString();
tmpLimite = roww["tempo_permanencia"].ToString();
cobrador = roww["cod_cobrador"].ToString();
}
cmd.Parameters.Add(new MySqlParameter("#numero_int", MySqlDbType.Int32)).Value = ide + 1; **//HERE THE ERROR STARTS**
cmd.Parameters.Add(new MySqlParameter("#parcela", MySqlDbType.VarChar)).Value = "1/1";
cmd.Parameters.Add(new MySqlParameter("#tipo_pessoa", MySqlDbType.Int32)).Value = tipo_pessoa;
cmd.Parameters.Add(new MySqlParameter("#matricula", MySqlDbType.Int32)).Value = retorno.Matricula;
cmd.Parameters.Add(new MySqlParameter("#cod_dependente", MySqlDbType.Int32)).Value = retorno.Cod_Dep;
cmd.Parameters.Add(new MySqlParameter("#ev_financeiro", MySqlDbType.Int32)).Value = eventoF;
cmd.Parameters.Add(new MySqlParameter("#quantidade", MySqlDbType.Int32)).Value = 1;
cmd.Parameters.Add(new MySqlParameter("#valor_unitario", MySqlDbType.Double)).Value = Convert.ToDouble(cash);
cmd.Parameters.Add(new MySqlParameter("#valor_total", MySqlDbType.Double)).Value = Convert.ToDouble(cash);
cmd.Parameters.Add(new MySqlParameter("#dt_lancamento", MySqlDbType.Date)).Value = Convert.ToDateTime(dt_lancamento); // X
cmd.Parameters.Add(new MySqlParameter("#dt_vencimento", MySqlDbType.Date)).Value = ent; // X
cmd.Parameters.Add(new MySqlParameter("#dt_pagamento", MySqlDbType.Date)).Value = saida; // X
cmd.Parameters.Add(new MySqlParameter("#dt_insercao", MySqlDbType.DateTime)).Value = saida; // X
cmd.Parameters.Add(new MySqlParameter("#dt_insercao_pagamento", MySqlDbType.DateTime)).Value = insercao_pagto; // X
cmd.Parameters.Add(new MySqlParameter("#referencia", MySqlDbType.Date)).Value = referencia;
cmd.Parameters.Add(new MySqlParameter("#cobrador_lancto", MySqlDbType.VarChar)).Value = cobrador;
cmd.Parameters.Add(new MySqlParameter("#cobrador_pagto", MySqlDbType.VarChar)).Value = cobrador;
cmd.Parameters.Add(new MySqlParameter("#usr_lancto", MySqlDbType.VarChar)).Value = usre;
cmd.Parameters.Add(new MySqlParameter("#forma_pagto", MySqlDbType.Int32)).Value = 1;
cmd.ExecuteNonQuery();
#endregion
#region TratamentoUpdate
cmd.CommandText = Update;
cmd.Parameters.Add(new MySqlParameter("#dt_saida", MySqlDbType.DateTime)).Value = conv.Dt_Saida;
cmd.Parameters.Add(new MySqlParameter("#usr_saida", MySqlDbType.VarChar)).Value = usuario;
cmd.Parameters.Add(new MySqlParameter("#status", MySqlDbType.VarChar)).Value = status;
cmd.Parameters.Add(new MySqlParameter("#deb", MySqlDbType.Int32)).Value = deb;
cmd.Parameters.Add(new MySqlParameter("#nome", MySqlDbType.VarChar)).Value = retorno.Nome;
cmd.ExecuteNonQuery();
#endregion
ta.Commit();
}
}
}
Cmd.Parameter.Clear() Is not a good practise. Here's the ANSWER.
Outside the ForEachLoop :
Cmd.Parameter.Add(new MySqlParameter("#Hellow", MySqlDataType));
Inside the ForEachLoop
Cmd.Parameter["#Hellow"].Value = anyValueOrVariable;
You're adding the same parameters to your command over and over again in the loop. The exception is telling you the problem.
Either store your parameters outside the loop and reset the values or clear the parameters each time through the loop.
The quickest solution would be something like this:
#region TratamentoInsert
cmd.Parameters.Clear();//<--clear all the parameters.
cmd.CommandText = Insert;
Not sure if that's the exact code to clear the parameters collection or not but I'm late for a flight and can't check. It'll be something like that.
You are adding parameters to cmd on every loop. Create the parameters at the same point you initialize cmd, or clear them before adding again.
Related
Oracle error ORA-12571 encountered for Select Statement
I'm trying to read table data from ORACLE with Parameter binding in c#. While executing the dataAdapter I'm getting ORA-12571 exception. Below is my code for reading multiple data at the same time. public DataTable SelectFromServer(string qualifiedDBName, DataTable dataTable) { try { if (this.Con.State == ConnectionState.Closed) { this.OpenConnection(); } DataTable resultTable = new DataTable(); dataTable.TableName = qualifiedDBName; DbProviderFactory factory = DbProviderFactories.GetFactory(this.Con); using (DbCommand command = factory.CreateCommand()) { command.Connection = this.Con; command.CommandText = this.GenerateSqlToSelect(factory,command,dataTable); DbDataAdapter adapter = factory.CreateDataAdapter(); adapter.SelectCommand = command; adapter.Fill(resultTable); return resultTable; } } catch (Exception exc) { throw exc; } } Below is the method where I used to generate Select Query private string GenerateSqlToSelect(DbProviderFactory factory, DbCommand command, DataTable table) { //var values1 = new List<string>(); var SelectQuery = new StringBuilder(); var data = table.ToArray(); var syntax = new OracleSyntax(); command.GetType().GetProperty("ArrayBindCount").SetValue(command, table.Rows.Count, null); for (var i = 0; i < table.Columns.Count; i++) { var names = new StringBuilder(); var values = new StringBuilder(); var column = table.Columns[i]; OracleParameter parameter = new OracleParameter(); parameter.ParameterName = column.ColumnName; parameter.Direction = ParameterDirection.Input; parameter.DbType = column.DataType.GetDbType(); parameter.Value = data[i]; parameter.ArrayBindSize = GetDataLength(data[i]); if (SelectQuery.Length > 0) { SelectQuery.Append(" and "); } names.AppendFormat("{0}", column.ColumnName); values.AppendFormat("{0}{1}", syntax.ParameterPrefix, column.ColumnName); SelectQuery.AppendFormat("{0} = {1}", names, values); command.Parameters.Add(parameter); } string operationString = "SELECT * FROM"; string sqlQuery = string.Format("{0} {1} WHERE {2}", operationString, this.FormatByQuote(syntax,table.TableName), SelectQuery); return sqlQuery; } private int[] GetDataLength(object[] objs) { List<int> dataLengthIterator = new List<int>(); foreach (object obj in objs) { dataLengthIterator.Add(obj.ToString().Length); } return dataLengthIterator.ToArray(); } this.FormatByQuote() method is nothing but getting a quoted TableName. Output of GenerateSqlToSelect() method is SELECT * FROM "CUSTOMER_MASTER" WHERE USER_ID= :USER_ID and LINE_NUMBER = :LINE_NUMBER The Query is generating based upon the DataTable input Tried multiple workarounds but could not get the reason why the exception is occurring.
Return output parameter from C#
I have a procedure with 2 input parameters and 2 output parameters. Currently its working fine. However, i want to take the two output parameters of the procedure and store it in a variable. Can anyone guide me how. Stored procedure code: create or replace PROCEDURE P_LOGIN_USER ( USERNAME IN VARCHAR2 , ENCRYPTIONKEY IN VARCHAR2 , OUT_STATUS OUT VARCHAR2 , OUT_STATUS_DESC OUT VARCHAR2 ) ------------------------Procedure Code END P_LOGIN_USER C# Code where i assign the input parameters. Missing part is getting the output parameters OracleCommand cmd = new OracleCommand("P_LOGIN_USER", OrCon); cmd.CommandType = CommandType.StoredProcedure; OracleParameter in_username = new OracleParameter(); in_username.OracleDbType = OracleDbType.Varchar2; in_username.Direction = ParameterDirection.Input; in_username.Size = 500; in_username.Value = username; cmd.Parameters.Add(in_username); OracleParameter in_ecnryptionkey = new OracleParameter(); in_ecnryptionkey.OracleDbType = OracleDbType.Varchar2; in_ecnryptionkey.Direction = ParameterDirection.Input; in_ecnryptionkey.Size = 500; in_ecnryptionkey.Value = password; cmd.Parameters.Add(in_ecnryptionkey); OracleParameter out_1 = new OracleParameter(); out_1.OracleDbType = OracleDbType.Varchar2; out_1.Direction = ParameterDirection.Output; out_1.Size = 500; cmd.Parameters.Add(out_1); OracleParameter out_2 = new OracleParameter(); out_2.OracleDbType = OracleDbType.Varchar2; out_2.Direction = ParameterDirection.Output; out_2.Size = 500; cmd.Parameters.Add(out_2); try { OrCon.Open(); cmd.ExecuteNonQuery(); cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "P_LOGIN_USER"; cmd.Parameters.Add(new OracleParameter { ParameterName = "result", Size = 1, Direction = ParameterDirection.ReturnValue, OracleDbType = OracleDbType.Varchar2 }); } catch (OracleException ex) { Console.Write(ex.Message); } OrCon.Close();
You can get the value out output parameter like this. string outputStatus = Convert.ToString(cmd.Parameters["#OUT_STATUS "].Value); Put the above line after ExecuteNonQuery()
Stored procedure code: create or replace PROCEDURE P_LOGIN_USER ( USERNAME IN VARCHAR2 , ENCRYPTIONKEY IN VARCHAR2 , p_recordset OUT SYS_REFCURSOR) IS BEGIN OPEN p_recordset FOR SELECT OUT_STATUS ,OUT_STATUS_DESC ..... END C#: using (var reader = cmd.ExecuteReader()) { List<ListModel> obj= reader.MapToList<ListModel>(); return obj; } ## **MapToList** ## public static List<T> MapToList<T>(this DbDataReader dr) where T : new() { if (dr != null && dr.HasRows) { var entity = typeof(T); var entities = new List<T>(); var propDict = new Dictionary<string, PropertyInfo>(); var props = entity.GetProperties(BindingFlags.Instance | BindingFlags.Public); propDict = props.ToDictionary(p => p.Name.ToUpper(), p => p); List<string> log = new List<string>(); while (dr.Read()) { try { T newObject = new T(); for (int index = 0; index < dr.FieldCount; index++) { var columnname = dr.GetName(index).ToUpper(); if (propDict.ContainsKey(dr.GetName(index).ToUpper())) { var info = propDict[dr.GetName(index).ToUpper()]; if ((info != null) && info.CanWrite) { try { var val = dr.GetValue(index); info.SetValue(newObject, (val == DBNull.Value) ? null : val, null); } catch (Exception ex) { var columename= dr.GetName(index).ToUpper(); var val= dr.GetValue(index); var getype = val.GetType(); log.Add(columename + ":" + val + ":" + getype.ToString()); } } } } entities.Add(newObject); } catch (Exception ex) { } } return entities; } return null; }
Getting a bit value from stored procedure in C#
The situation is following, i have a stored procedure in SQL Server , this has a few output parameters, one of them is a bit type, what I want is to take the value of that parameter, but I have a conversion error, InvalidCastException. This is my code: public void exec() { String strConnString = "Server=.\\SQLEXPRESS;Database=recalls;Integrated Security=true"; SqlConnection con = new SqlConnection(strConnString); SqlCommand cmd = new SqlCommand(); cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "findVinCamp"; int c = Int32.Parse(campaing.Text); cmd.Parameters.Add("#camp", SqlDbType.Int).Value = c; cmd.Parameters.Add("#vin", SqlDbType.VarChar, 100).Value = vin.Text; cmd.Parameters.Add("#desc", SqlDbType.NVarChar, 255).Direction = ParameterDirection.Output; cmd.Parameters.Add("#st", SqlDbType.VarChar, 50).Direction = ParameterDirection.Output; cmd.Parameters.Add("#bit", SqlDbType.Bit).Direction = ParameterDirection.Output; cmd.Connection = con; con.Open(); cmd.ExecuteNonQuery(); bit = (int)cmd.Parameters["#bit"].Value; //Exception Here if (bit == 1) { desc.Text = cmd.Parameters["#desc"].Value.ToString(); stt.Text = cmd.Parameters["#st"].Value.ToString(); camp = cmd.Parameters["#camp"].Value.ToString(); if (stt.Text.Equals("APPLIED")) { stt.ForeColor = System.Drawing.Color.LawnGreen; } else { stt.ForeColor = System.Drawing.Color.Firebrick; label3.Enabled = true; newstatus.Enabled = true; update.Enabled = true; } } else { MessageBox.Show("Doesn't exits!"); } } I'm trying to assign the bit parameter to a int variable. Any question post on comments.
I change the (int) to this, now works perfectly: Boolean lol = Convert.ToBoolean(cmd.Parameters["#bit"].Value);
Use this following Line bool isConfirmed = (bool)cmd.Parameters["#bit"].Value; if(isConfirmed ){ desc.Text = cmd.Parameters["#desc"].Value.ToString(); stt.Text = cmd.Parameters["#st"].Value.ToString(); camp = cmd.Parameters["#camp"].Value.ToString(); if (stt.Text.Equals("APPLIED")) { stt.ForeColor = System.Drawing.Color.LawnGreen; } else { stt.ForeColor = System.Drawing.Color.Firebrick; label3.Enabled = true; newstatus.Enabled = true; update.Enabled = true; } } else{ MessageBox.Show("Doesn't exits!"); } **UPDATE: **if the bit column allows nulls -- many ways you can do this bool isConfirmed = cmd.Parameters["#bit"].Value as bool? ?? null; and also read this- SQL Server Data Types and Their .NET Framework Equivalents
I believe a bit will convert to a boolean. Which should make your code a bit simpler too. i.e. ... var bit = (bool)cmd.Parameters["#bit"].Value; if (bit) { ...
You are trying to convert your boolean output to INT, please convert it in Boolean: bool bitValue= Convert.ToBoolean(cmd.Parameters["#bit"].Value)
C#, MySQL - fatal error encountered during command execution- Checked other solutions, something I am Missing
I have looked at the other questions with this title and I think the problem is something local with my code that I am missing. The function that this button preforms is to calculate the points/rewards that a person earns based on the transaction total. For example, $10 = 1 point, 19=1 point, 20=2. 10 Points = 1 Rewards points, which is equal to a ten dollar credit. My Code receives the title error message. I will include the entire function for completeness. private void button1_Click(object sender, EventArgs e) { try{ string cs = #"server=localhost;userid=root;password=root;database=dockingbay94"; MySqlConnection conn; //MySqlDataReader rdr = null; using (conn = new MySqlConnection(cs)); if (conn.State != ConnectionState.Open) { conn.Open(); } string input = textBox2.Text; MySqlCommand myCommand2 = conn.CreateCommand(); myCommand2.CommandText = "SELECT Points FROM members WHERE id = #input"; MySqlDataAdapter MyAdapter2 = new MySqlDataAdapter(); MyAdapter2.SelectCommand = myCommand2; double transaction = Convert.ToDouble(textBox3.Text); double tmp_transaction = Math.Floor(transaction); string transaction_date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); double pointsbefore = (tmp_transaction / 10.0); int currentpoints = Convert.ToInt32(pointsbefore); int rewards = 0; int oldpoints = 0; string temp = ""; pointsbefore = Math.Floor(pointsbefore); int new_points; double tmp_rewards = 0.0; double tmp_points; int new_rewards; oldpoints = (int)myCommand2.ExecuteScalar(); new_points = currentpoints + oldpoints; tmp_points = new_points / 10; int tmp_rewards2 = 0; if (new_points > 10) { tmp_rewards = Math.Floor(tmp_points); tmp_rewards2 = Convert.ToInt32(tmp_rewards); } else if (new_points == 10) { tmp_rewards2 = 1; } else { tmp_rewards2 = 0; } new_rewards = rewards + tmp_rewards2; int points_left = 0; if (new_points > 10) { for (int i = 10; i < new_points; i++) { points_left++; } } else if (new_points == 10) { points_left = 0; } else if (new_points < 10) { for (int i = 0; i < new_points; i++) { points_left++; } } string query = "UPDATE members Set Points=#Points, rewards_collected=#Rewards, transaction_total=#Transaction, transaction_date=#TransactionDate" + "WHERE id = #input;"; MySqlCommand cmdDataBase = new MySqlCommand(query, conn); cmdDataBase.Parameters.Add("#input", SqlDbType.Int).Value = Convert.ToInt32(textBox2.Text); cmdDataBase.Parameters.AddWithValue("#Points", new_points); cmdDataBase.Parameters.AddWithValue("#Rewards", new_rewards); cmdDataBase.Parameters.AddWithValue("#Transaction", textBox3.Text); cmdDataBase.Parameters.AddWithValue("#TransationDate", transaction_date); MySqlDataReader myReader2; myReader2 = cmdDataBase.ExecuteReader(); MessageBox.Show("Data Updated"); if(conn.State == ConnectionState.Open){ conn.Close(); } } catch(Exception ex) { MessageBox.Show(ex.Message); } } } I am not sure where the error could be. Probably not sending the right value. Thanks
This line is wrong using (conn = new MySqlConnection(cs)); Remove the semicolon and include everything that needs the MySqlConnection variable inside a {} block using (MySqlConnection conn = new MySqlConnection(cs)) { // No need to test if the connection is not open.... conn.Open(); ......... // Not needed (at least from your code above // MySqlDataAdapter MyAdapter2 = new MySqlDataAdapter(); // MyAdapter2.SelectCommand = myCommand2; ... calcs follow here // Attention here, if the query returns null (no input match) this line will throw oldpoints = (int)myCommand2.ExecuteScalar(); .... other calcs here MySqlCommand cmdDataBase = new MySqlCommand(query, conn); cmdDataBase.Parameters.Add("#input", SqlDbType.Int).Value = Convert.ToInt32(textBox2.Text); cmdDataBase.Parameters.AddWithValue("#Points", new_points); cmdDataBase.Parameters.AddWithValue("#Rewards", new_rewards); cmdDataBase.Parameters.AddWithValue("#Transaction", textBox3.Text); cmdDataBase.Parameters.AddWithValue("#TransationDate", transaction_date); // Use ExecuteNonQuery for INSERT/UPDATE/DELETE and other DDL calla cmdDataBase.ExecuteNonQuery(); // Not needed // MySqlDataReader myReader2; // myReader2 = cmdDataBase.ExecuteReader(); // Not needed, the using block will close and dispose the connection if(conn.State == ConnectionState.Open) conn.Close(); } There is also another error in the final query. Missing a space between #TransactionDate parameter and the WHERE clause. In cases where a long SQL command text is needed I find very useful the verbatim string line character continuation # string query = #"UPDATE members Set Points=#Points, rewards_collected=#Rewards, transaction_total=#Transaction, transaction_date=#TransactionDate WHERE id = #input;";
How to use Parameters to convert to proper data types. with SQL Query?
I am trying to save some values to data table in MS SQL , but i have some problem with the Data types . i need to use Parameters to convert those values to proper data types this is my table ,,, Table image this is the code that i'm using to pass values to the database ,, i need to use Parameters to convert data, please help me to do it ... private void InsertRec(StringCollection sc) { var conn = new SqlConnection(GetConnectionString()); var sb = new StringBuilder(string.Empty); var splitItems = (string[])null; foreach (string item in sc) { const string sqlStatement = "INSERT INTO DEL_PurchasesLines1 (DealerCode,InvoiceNo,InvoiceDate,ItemIdentityCode,PurchasingPrice,DiscountRate,Discount,IssueMode,Qty,Total,ExpireDate,BatchNumber,UploadedStatus,InsertedDate,UploadedDate,Force,Principle,NewTotal) VALUES"; if (item.Contains(",")) { splitItems = item.Split(",".ToCharArray()); sb.AppendFormat("{0}('{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}','{13}','{14}','{15}','{16}','{17}','{18}'); ", sqlStatement, splitItems[0], splitItems[1], splitItems[2], splitItems[3], splitItems[4], splitItems[5], splitItems[6], splitItems[7], splitItems[8], splitItems[9], splitItems[10], splitItems[11], splitItems[12], splitItems[13], splitItems[14], splitItems[15], splitItems[16], splitItems[17]); } } try { conn.Open(); SqlCommand cmd = new SqlCommand(sb.ToString(), conn) { CommandType = CommandType.Text }; cmd.ExecuteNonQuery(); Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "Script", "alert('Records Successfuly Saved!');", true); } catch (System.Data.SqlClient.SqlException ex) { string msg = "Insert Error:"; msg += ex.Message; throw new Exception(msg); } finally { conn.Close(); } } this is how i take the values in to query. protected void btnSaave_Click(object sender, EventArgs e) { int rowIndex = 0; StringCollection sc = new StringCollection(); if (ViewState["CurrentData"] != null) { DataTable dtCurrentTable = (DataTable)ViewState["CurrentData"]; DataRow drCurrentRow = null; if (dtCurrentTable.Rows.Count > 0) { for (int i = 1; i <= dtCurrentTable.Rows.Count; i++) { var dtDealerCode = txtIDealerCode.Text; var dtInvoiceNo = txtInvoiceNumber.Text; var dtInvoiceDate = txtInvoiceDate.Text; var dtItemIdentityCode = (Label)GridView1.Rows[rowIndex].Cells[1].FindControl("ItemCode"); var dtPurchasingPrice = (Label)GridView1.Rows[rowIndex].Cells[3].FindControl("UnitPrice"); var dtDiscountRate = txtDiscount.Text; var dtDiscount = txtProductDiscount.Text; var dtIssueMode = ddlIssueMode.SelectedValue; var dtQty = (Label)GridView1.Rows[rowIndex].Cells[6].FindControl("Quantity"); var dtTotal = (Label)GridView1.FooterRow.FindControl("GetTotal"); var dtExpireDate = (Label)GridView1.Rows[rowIndex].Cells[5].FindControl("ExpiaryDate"); var dtBatchNumber = (Label)GridView1.Rows[rowIndex].Cells[4].FindControl("Batch"); var dtUploadedStatus = txtInvoiceDate.Text; var dtInsertedDate = "1"; var dtUploadedDate = txtInvoiceDate.Text; var dtForce = txtForce.Text; var dtPrinciple = txtPrinciple.Text; var NewTotal = (Label)GridView1.FooterRow.FindControl("GetQuantity"); sc.Add(dtDealerCode + "," + dtInvoiceNo + "," + dtInvoiceDate + "," + dtItemIdentityCode.Text + "," + dtPurchasingPrice.Text + "," + dtDiscountRate + "," + dtDiscount + "," + dtIssueMode + "," + dtQty.Text + "," + dtTotal.Text + "," + dtExpireDate + "," + dtBatchNumber.Text + "," + dtUploadedStatus + "," + dtInsertedDate + "," + dtUploadedDate + "," + dtForce + "," + dtPrinciple + "," + dtPrinciple + "," + NewTotal.Text); rowIndex++; } InsertRec(sc); } } }
The correct way is to build a method that asks for the specific values it expects, either by having an parameter for each item or via a class type, ie either this: private void InsertRec(DEL_PurchasesLines1 lineToInsert) where DEL_PurchasesLines1 is a class you will create (named after the table), or this: private void InsertRec(string DealerCode,string InvoiceNo,DateTime InvoiceDate, string ItemIdentityCode,decimal PurchasingPrice, decimal DiscountRate, decimal Discount,string IssueMode,decimal Qty,decimal Total, DateTime ExpireDate,string BatchNumber,string UploadedStatus, string InsertedDate,DateTime UploadedDate,string Force, decimal Principle,decimal NewTotal) FWIW, that many columns in a single table almost always means something is wrong with the table design, but I'll leave that alone for now. Going with the second method, your button click would look like this: protected void btnSave_Click(object sender, EventArgs e) { if (ViewState["CurrentData"] == null) return; DataTable dtCurrentTable = (DataTable)ViewState["CurrentData"]; if (dtCurrentTable.Rows.Count == 0) return; int rowIndex = 0; var dtDealerCode = txtIDealerCode.Text; var dtInvoiceNo = txtInvoiceNumber.Text; var dtInvoiceDate = DateTime.Parse(txtInvoiceDate.Text); var dtDiscountRate = decimal.Parse(txtDiscount.Text); var dtDiscount = decimal.Parse(txtProductDiscount.Text); var dtIssueMode = ddlIssueMode.SelectedValue; var dtUploadedStatus = DateTime.Parse(txtInvoiceDate.Text); var dtInsertedDate = "1"; //Really? var dtUploadedDate = DateTime.Parse(txtInvoiceDate.Text); var dtForce = txtForce.Text; var dtPrinciple = decimal.Parse(txtPrinciple.Text); for (int i = 1; i <= dtCurrentTable.Rows.Count; i++) { var dtItemIdentityCode = (Label)GridView1.Rows[rowIndex].Cells[1].FindControl("ItemCode"); var dtPurchasingPrice = decimal.Parse((Label)GridView1.Rows[rowIndex].Cells[3].FindControl("UnitPrice")); var dtQty = decimal.Parse((Label)GridView1.Rows[rowIndex].Cells[6].FindControl("Quantity")); var dtTotal = decimal.Parse((Label)GridView1.FooterRow.FindControl("GetTotal")); var dtExpireDate = DateTime.Parse((Label)GridView1.Rows[rowIndex].Cells[5].FindControl("ExpiaryDate")); var dtBatchNumber = (Label)GridView1.Rows[rowIndex].Cells[4].FindControl("Batch"); var NewTotal = decimal.Parse((Label)GridView1.FooterRow.FindControl("GetQuantity")); InsertRec(dtDealerCode,dtInvoiceNo,dtInvoiceDate,dtItemIdentityCode, dtPurchasingPrice,dtDiscountRate,dtDiscount,dtIssueMode,dtQty, dtTotal,dtExpireDate,dtBatchNumber,dtUploadedStatus,dtInsertedDate, dtUploadedDate,dtForce,dtPrinciple,NewTotal); rowIndex++; } } To bring it all together, InsertRec() will look like this: private void InsertRec(string DealerCode,string InvoiceNo,DateTime InvoiceDate, string ItemIdentityCode,decimal PurchasingPrice, decimal DiscountRate, decimal Discount,string IssueMode,decimal Qty,decimal Total, DateTime ExpireDate,string BatchNumber,string UploadedStatus, string InsertedDate,DateTime UploadedDate,string Force, decimal Principle,decimal NewTotal) { const string sqlStatement = "INSERT INTO DEL_PurchasesLines1 (" + "DealerCode,InvoiceNo,InvoiceDate,ItemIdentityCode,PurchasingPrice,DiscountRate,Discount,IssueMode,Qty,Total,ExpireDate,BatchNumber,UploadedStatus,InsertedDate,UploadedDate,Force,Principle,NewTotal" + ") VALUES (" + "#DealerCode, #InvoiceNo, #InvoiceDate, #ItemIdentityCode, #PurchasingPrice, #DiscountRate, #Discount, #IssueMode, #Qty, #Total, #ExpireDate, #BatchNumber, #UploadSTatus, #InsertedDate, #UploadedDate, #Force, #Principle, #NewTotal" + ")"; using (conn = new SqlConnection(GetConnectionString()) using (cmd = new SqlCommand(sqlStatement, conn)) { cmd.Parameters.Add("#DealerCode", SqlDbType.NVarChar, 10).Value = DealerCode; cmd.Parameters.Add("#InvoiceNo", SqlDbType.NVarChar, 10).Value = InvoiceNo; cmd.Parameters.Add("#InvoiceDate", SqlDbType.DateTime).Value = InvoiceDate; cmd.Parameters.Add("#ItemIdentityCode", SqlDbType.NVarChar, 10).Value = ItemIdentityCode; cmd.Parameters.Add("#PurchasingPrice", SqlDbType.Decimal).Value = PurchasingPrice; cmd.Parameters.Add("#DiscountRate", SqlDbType.Decimal).Value = DiscountRate; //... conn.Open(); cmd.ExecuteNonQuery(); } Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "Script", "alert('Records Successfuly Saved!');", true); } What you were doing with the StringBuilder and Format strings there was totally inappropriate, thanks to a little thing called Sql Injection. It's kind of important, so you should definitely do some reading about it. I also see that you're trying to group the inserts into a single batch. That's nice, but thanks to connection pooling it doesn't really get you much. It's also harder to do with correct query parameterization. It's not impossible, though, so I'll show you an example now using the other method signature, which makes it a bit easier: private void InsertRec(DEL_PurchasesLines1[] linesToInsert) { const string sqlBase = "INSERT INTO DEL_PurchasesLines1 (" + "(DealerCode,InvoiceNo,InvoiceDate,ItemIdentityCode,PurchasingPrice,DiscountRate,Discount,IssueMode,Qty,Total,ExpireDate,BatchNumber,UploadedStatus,InsertedDate,UploadedDate,Force,Principle,NewTotal)" + " VALUES "; const string valueBase = "{0}(#DealerCode{1}, #InvoiceNo{1}, #InvoiceDate{1}, #ItemIdentityCode{1}, #PurchasingPrice{1}, #DiscountRate{1}, #Discount{1}, #IssueMode{1}, #Qty{1}, #Total{1}, #ExpireDate{1}, #BatchNumber{1}, #UploadSTatus{1}, #InsertedDate{1}, #UploadedDate{1}, #Force{1}, #Principle{1}, #NewTotal{1})"; var sb = new StringBuilder(sqlBase); if (DEL_PurchasesLines1.Length > 1) sb.Append("(") var delimiter = ""; for (int i = 0;i<DEL_PurchasesLines1.Length;i++) { sb.AppendFormat(valueBase, i, delimiter); delimiter = ","; } if (DEL_PurchasesLines1.Length > 1) sb.Append(")") using (conn = new SqlConnection(GetConnectionString()) using (cmd = new SqlCommand(sqlStatement, conn)) { for (int i = 0;i<DEL_PurchasesLines1.Length;i++) { cmd.Parameters.Add("#DealerCode" + i, SqlDbType.NVarChar, 10).Value = linesToInsert[i].DealerCode; cmd.Parameters.Add("#InvoiceNo" + i, SqlDbType.NVarChar, 10).Value = linesToInsert[i].InvoiceNo; cmd.Parameters.Add("#InvoiceDate + i", SqlDbType.DateTime).Value = linesToInsert[i].InvoiceDate; cmd.Parameters.Add("#ItemIdentityCode" + i, SqlDbType.NVarChar, 10).Value = linesToInsert[i].ItemIdentityCode; cmd.Parameters.Add("#PurchasingPrice" + i, SqlDbType.Decimal).Value = linesToInsert[i].PurchasingPrice; cmd.Parameters.Add("#DiscountRate" + i, SqlDbType.Decimal).Value = linesToInsert[i].DiscountRate; //... } conn.Open(); cmd.ExecuteNonQuery(); } }
This is kind of some nasty code. I don't know if you are new to programming but you should use a Stored Procedure for this where the procedure defines the 14 or so parameters that need to be passed in as arguments. This will guide your code so that you add parameters for the parameterized stored procedure call, each argument will need to be strongly typed and this will guide you to make the right conversions for each column value of your table. You should also create a C# class that defines, as public properties all your table column values. Excuse the VB.NET but you will get the idea with this simple Data Access Layer (D.A.L) example snippet, the UpdateOffer could be renamed AddUpdateOffer and this could check to see whether the record exists or not by passing in the record id to the AddUpdate stored procedure if it is an update, if the record id is null the stored procedure knows to do an insert else update: Public Class Offer Public OfferID As Integer Public PropertyID As Integer Public AgentUserID As Integer Public AgentName As String Public BuyerUserID As Integer Public BuyerName As String Public BuyerType As String Public Offer As Integer Public NetOffer As Integer Public ClosingCost As Integer Public Allowances As Integer Public RepairCosts As Integer Public TotalCredits As Integer Public OfferType As String Public OfferDate As String Public ProxyOffer As Integer Public NetProxyOffer As Integer Public ResultResponse As SUBMIT_OFFER_RESULT 'Public ResultAcceptedOffer As Integer Public ResultAcceptedNetOffer As Integer 'Public ResultHighestOffer As Integer Public ResultHighestNetOffer As Integer Public Notifications As ArrayList = New ArrayList Public EarnestMoneyDeposit As Integer Public DownPayment As Integer Public TypeOfFinancing As String Public OfferStatus As String Public Note As String Public Visble As Boolean = True Public OfferStatusChangedDate As DateTime Public EstimatedCloseDate As DateTime Public SourceType As String Public Sub GetOffer(ByVal offerID As Integer) Dim offerDB As OSP.DataAccess.OfferDB = New OSP.DataAccess.OfferDB Dim rs As SqlClient.SqlDataReader rs = offerDB.GetOffer(offerID) Do While rs.Read Me.OfferID = offerID Me.PropertyID = rs("PROPERTY_ID") Me.AgentUserID = rs("AGENT_USER_ID") Me.BuyerUserID = IIf(IsDBNull(rs("BUYER_USER_ID")), 0, rs("BUYER_USER_ID")) Me.Offer = rs("OFFER") Me.NetOffer = rs("NET_OFFER") Me.TotalCredits = rs("TOTAL_CREDITS") Me.ProxyOffer = rs("PROXY_OFFER") Me.OfferType = rs("OFFERTYPE") Me.OfferDate = rs("OFFER_DATE") Me.DownPayment = IIf(IsDBNull(rs("DOWN_PAYMENT")), 0, rs("DOWN_PAYMENT")) Me.EarnestMoneyDeposit = IIf(IsDBNull(rs("EARNEST_MONEY_DEPOSIT")), 0, rs("EARNEST_MONEY_DEPOSIT")) Me.TypeOfFinancing = rs("TYPE_OF_FINANCING") Me.BuyerName = GlobalFunctions.DefaultString(rs("BUYER_NAME")) Me.BuyerType = GlobalFunctions.DefaultString(rs("BUYER_TYPE")) Me.AgentName = rs("OFFER_BY_NAME") Me.OfferStatus = GlobalFunctions.DefaultString(rs("OFFER_STATUS")) Me.Note = GlobalFunctions.DefaultString(rs("NOTE")) Me.OfferStatusChangedDate = IIf(IsDBNull(rs("OFFER_STATUS_CHANGED_DATE")), Me.OfferStatusChangedDate, rs("OFFER_STATUS_CHANGED_DATE")) Me.Visble = IIf(IsDBNull(rs("VISIBLE")), True, rs("VISIBLE")) Me.EstimatedCloseDate = IIf(IsDBNull(rs("ESTIMATED_CLOSE_DATE")), DateTime.MinValue, rs("ESTIMATED_CLOSE_DATE")) Loop Try If Not rs.IsClosed Then rs.Close() : rs = Nothing End If If Not offerDB Is Nothing Then offerDB.Dispose() : offerDB = Nothing End If Catch : End Try End Sub Public Function UpdateOffer() As Integer Dim offerDB As OSP.DataAccess.OfferDB = New OSP.DataAccess.OfferDB Return offerDB.UpdateOffer(Me) End Function End Class Public Class OfferDB Implements System.IDisposable Dim db As SQLDatabase Public Sub New() db = New SQLDatabase(GlobalSettings.GetDefaultConnectionString) End Sub Public Sub Dispose() Implements System.IDisposable.Dispose If Not db Is Nothing Then db = Nothing End If End Sub Public Function GetOffer(ByVal offerID As Integer) As SqlClient.SqlDataReader Dim dbCommand As DbCommand = db.GetStoredProcCommand("OSP_GET_OFFER") db.AddInParameter(dbCommand, "#OFFER_ID", SqlDbType.Int, offerID) Try Return db.ExecuteReader(dbCommand) Catch ex As Exception Dim rethrow As Boolean = ExceptionPolicy.HandleException(ex, "EXCEPTION_CRITICAL") If (rethrow) Then Throw End If End Try End Function Public Function UpdateOffer(ByVal offer As OSP.Offer) As Integer Dim dbCommand As DbCommand = db.GetStoredProcCommand("OSP_UPDATE_OFFER") db.AddInParameter(dbCommand, "#OFFER_ID", SqlDbType.Int, offer.OfferID) db.AddInParameter(dbCommand, "#BUYER_USER_ID", SqlDbType.Int, offer.BuyerUserID) db.AddInParameter(dbCommand, "#OFFER", SqlDbType.Int, offer.Offer) db.AddInParameter(dbCommand, "#TOTAL_CREDITS", SqlDbType.Int, offer.TotalCredits) db.AddInParameter(dbCommand, "#OFFER_TYPE", SqlDbType.VarChar, offer.OfferType) db.AddInParameter(dbCommand, "#OFFER_DATE", SqlDbType.VarChar, offer.OfferDate) db.AddInParameter(dbCommand, "#TYPE_OF_FINANCING", SqlDbType.VarChar, offer.TypeOfFinancing) db.AddInParameter(dbCommand, "#DOWN_PAYMENT", SqlDbType.Int, offer.DownPayment) db.AddInParameter(dbCommand, "#EARNEST_MONEY_DEPOSIT", SqlDbType.Int, offer.EarnestMoneyDeposit) db.AddInParameter(dbCommand, "#OFFER_STATUS", SqlDbType.VarChar, offer.OfferStatus) db.AddInParameter(dbCommand, "#NOTE", SqlDbType.VarChar, offer.Note) If Not offer.OfferStatusChangedDate = DateTime.MinValue Then db.AddInParameter(dbCommand, "#OFFER_STATUS_CHANGED_DATE", SqlDbType.DateTime, offer.OfferStatusChangedDate) End If Try Return db.ExecuteScalar(dbCommand) Catch ex As Exception Dim rethrow As Boolean = ExceptionPolicy.HandleException(ex, "EXCEPTION_CRITICAL") If (rethrow) Then Throw End If End Try End Function End Class