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

Categories