Why won't my code write to SQL? - c#

I'm writing an app to store texts to an SQL database, but my code throws an exception saying "the variable name #par1 has already been declared", I'm not sure how to get this working and would like some help fixing this if possible please =]
offending code is below
private void SMSGetter()
{
try {
DecodedShortMessage[] messages = Comm.ReadMessages(PhoneMessageStatus.All, PhoneStorageType.Sim);
SqlConnection Conn = new SqlConnection("Data Source=*********;Initial Catalog=********;User ID=**********;Password=***********");
SqlCommand com = new SqlCommand();
com.Connection = Conn;
Conn.Open();
foreach (DecodedShortMessage message in messages)
{
//com.CommandText = ("INSERT INTO SMSArchives(Message,Blacklist) VALUES ('" + message.Data.UserDataText + "', 'Yes')");
//com.ExecuteNonQuery();
com.CommandText = ("INSERT INTO SMSArchives(Message,Blacklist) VALUES (#par1,#par2)");
com.Parameters.AddWithValue("#par1", message.Data.UserDataText);
com.Parameters.AddWithValue("#par2", "Yes");
com.ExecuteNonQuery();
}
Conn.Close();
}
catch (Exception ex) {
Log(ex.ToString());
}
}

You are using the same command for every iteration, but adding parameters each time. Try calling
com.Parameters.Clear();
at the end of each loop iteration. You could also pre-create the parameters and just set the .Value per iteration - probably marginally faster.
Also: fix the SQL injection hole :)

private void SMSGetter()
{
Log("Getter Fired");
//var message = GSM.ReadMessage(4);
//GSM.ReadMessage(4);
//TcpClientChannel client = new TcpClientChannel();
//ChannelServices.RegisterChannel(client, false);
//string url = "*******";
//ISmsSender smssender = (ISmsSender)Activator.GetObject(typeof(ISmsSender), url);
try
{
DecodedShortMessage[] messages = Comm.ReadMessages(PhoneMessageStatus.All, PhoneStorageType.Sim);
SqlConnection Conn = new SqlConnection("Data Source=*********;Initial Catalog=********;User ID=**********;Password=***********");
SqlCommand com = new SqlCommand();
com.Connection = Conn;
Conn.Open();
com.CommandText = ("INSERT INTO SMSArchives(Message,Blacklist) VALUES (#par1,#par2)");
com.Parameters.Add("#par1");
com.Parameters.Add("#par2");
foreach (DecodedShortMessage message in messages)
{
com.Parameters["#par1"].value = message.Data.UserDataText;
com.Prepare(); //fix SQL injection :)
com.ExecuteNonQuery();
}
Conn.Close();
}
catch (Exception ex)
{
Log(ex.ToString());
}
}

You are adding the parameters at every iteration in foreach. Consider the following:
com.CommandText = ("INSERT INTO SMSArchives(Message,Blacklist) VALUES (#par1,#par2)");
command.Parameters.Add(new SqlParameter("#par1", ""));
com.Parameters.AddWithValue("#par2", "Yes");
foreach (DecodedShortMessage message in messages)
{
command.Parameters["#par1"].Value = message.Data.UserDataText;
com.ExecuteNonQuery();
}

Related

I have a listview with items which I want to insert into a SQL Server database

I want to save content of a listview into a SQL Server database.
I've tried the commented code but get an error
Must declare scalar variable #Description
Code:
private void btnFinish_Click(object sender, EventArgs e)
{
SqlCommand cmd = new SqlCommand();
try
{
foreach (ListViewItem item in lvregion.Items)
{
SqlConnection conn;
SqlCommand comm;
string connectionString = ConfigurationSettings.AppSettings["conn"];
conn = new SqlConnection(connectionString);
comm = new SqlCommand(
"INSERT INTO Region (RegionDescription, Fname, Lname) " +
"VALUES (#RegionDescription, #Fname, #Lname)", conn);
//cmd.Parameters.AddWithValue("RegionDescription", item.Text.Trim());
//cmd.Parameters.AddWithValue("fname", item.SubItems[1].Text.Trim());
//cmd.Parameters.AddWithValue("lname", item.SubItems[2].Text.Trim());
cmd.Parameters.Add("RegionDescription", SqlDbType.VarChar,40);
cmd.Parameters.AddWithValue("RegionDescription", item.Text.Trim());
cmd.Parameters.Add("Fname", SqlDbType.VarChar,40);
cmd.Parameters.AddWithValue("Fname", item.SubItems[1].Text.Trim());
cmd.Parameters.Add("Lname", SqlDbType.VarChar,40);
cmd.Parameters.AddWithValue("Lname", item.SubItems[2].Text.Trim());
try
{
conn.Open();
comm.ExecuteNonQuery();
}
catch (Exception)
{
throw;
}
finally
{
conn.Close();
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Welcome to Stackoverflow,
First up, I wouldn't recommend creating a new connection within your foreach to add items to your table.
Here's what I'd recommend using instead:
try
{
string connectionString = ConfigurationSettings.AppSettings["conn"];
using (SqlConnection conn = new SqlConnection(connectionString))
{
SqlCommand cmd;
conn.Open();
string cmdString = #"INSERT INTO Region (RegionDescription, Fname, Lname)
VALUES (#RegionDescription, #Fname, #Lname)";
foreach (ListViewItem item in lvregion.Items)
{
cmd = new SqlCommand(cmdString, conn);
cmd.Parameters.Add("#RegionDescription", SqlDbType.VarChar, 40).Value = item.Text.Trim();
cmd.Parameters.Add("#Fname", SqlDbType.VarChar, 40).Value = item.SubItems[1].Text.Trim();
cmd.Parameters.Add("#Lname", SqlDbType.VarChar, 40).Value = item.SubItems[2].Text.Trim();
cmd.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
(Or at least this should have you on the right path.)

Error with Connection property has not been initialized

Well, I work little bit with C # and I'm starting to work with Database with C # now, I've googled in several places and I am unable to identify where it is wrong, everywhere say I need to open a connection, but it is already open .
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\v11.0;Integrated Security=True;AttachDbFilename=C:\Users\Gustavo\Documents\Visual Studio 2013\Projects\hour\hour\Database1.mdf");
con.Open();
try
{
string query = "INSERT INTO [Table] (name, time) VALUES ('test',1)";
SqlCommand cmd = new SqlCommand(query);
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
Use using, takes care of the closing and disposal for you just in case you forget to do it explicitly. Put it inside the try, you have the connection open command outside the try so it wont catch any connection error. You probably want to look at parameterizing your command too.
using (SqlConnection conn = new SqlConnection(#"Data Source=(LocalDB)\v11.0;Integrated Security=True;AttachDbFilename=C:\Users\Gustavo\Documents\Visual Studio 2013\Projects\hour\hour\Database1.mdf"))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("INSERT INTO [Table] (name, time) VALUES (#name,#time)", conn))
{
cmd.Parameters.AddWithValue("#name", "test");
cmd.Parameters.AddWithValue("#time", 1);
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
}
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\v11.0;Integrated Security=True;AttachDbFilename=C:\Users\Gustavo\Documents\Visual Studio 2013\Projects\hour\hour\Database1.mdf");
try
{
string query = "INSERT INTO [Table] (name, time) VALUES ('test',1)";
SqlCommand cmd = new SqlCommand(query,con);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
you need to assign the command to the connection. eg:
private static void ReadOrderData(string connectionString)
{
string queryString =
"SELECT OrderID, CustomerID FROM dbo.Orders;";
using (SqlConnection connection = new SqlConnection(
connectionString))
{
//----
SqlCommand command = new SqlCommand(
queryString, connection);
//----
connection.Open();
SqlDataReader reader = command.ExecuteReader();
try
{
while (reader.Read())
{
Console.WriteLine(String.Format("{0}, {1}",
reader[0], reader[1]));
}
}
finally
{
// Always call Close when done reading.
reader.Close();
}
}
}

How can I add values from a foreach loop into SQL?

I have an SMS app in the form of a windows service, I need to iterate through a collection containing the messages stored on the GSM modem's sim card, However my current code will not compile with the following error;
Operator '+' cannot be applied to operands of type 'string' and 'method group'
I have attempted to nest my SQL commands within the foreach loop, but this as mentioned will not compile, could anyone help?
I do intend to Parameterize by the way! this is just a proof of concept!
code is below
private void SMSGetter()
{
Log("Getter Fired");
//var message = GSM.ReadMessage(4);
//GSM.ReadMessage(4);
//TcpClientChannel client = new TcpClientChannel();
//ChannelServices.RegisterChannel(client, false);
//string url = "*********************";
//ISmsSender smssender = (ISmsSender)Activator.GetObject(typeof(ISmsSender), url);
try
{
DecodedShortMessage[] messages = Comm.ReadMessages(PhoneMessageStatus.All, PhoneStorageType.Sim);
SqlConnection Conn = new SqlConnection("Data Source=*********;Initial Catalog=********;User ID=**********;Password=**********");
SqlCommand com = new SqlCommand();
com.Connection = Conn;
Conn.Open();
foreach (DecodedShortMessage message in messages)
{
com.CommandText = ("INSERT INTO SMSArchives(Message,Blacklist) VALUES ('" +message.ToString + "', 'Yes')");
com.ExecuteNonQuery();
}
Conn.Close();
return;
}
catch (Exception ex)
{
Log(ex.ToString());
}
}
foreach (DecodedShortMessage message in messages)
{
com.CommandText = ("INSERT INTO SMSArchives(Message,Blacklist) VALUES (#par1,#par2)");
com.Parameters.AddWithValue( "#par1",message.ToString());
com.Parameters.AddWithValue("#par2","Yes");
com.ExecuteNonQuery();
}
your Command Text should be
com.CommandText = ("INSERT INTO SMSArchives(Message,Blacklist) VALUES ('" + message.Tostring() + "', 'Yes')");
You need to add parens after ToString.
'" +message.ToString() + "'
As Jon points out, it would be better to use parameters instead:
com.CommandText = ("INSERT INTO SMSArchives(Message,Blacklist) VALUES (#Message, #Blacklist)");
SqlParameter messageParam = new SqlParameter("#Message", System.Data.SqlDbType.NVarChar, 8000);
SqlParameter blacklistParam = new SqlParameter("#Blacklist", System.Data.SqlDbType.VarChar, 10);
messageParam.Value = message.ToString();
blacklistParam.Value = "Yes";
com.Parameters.Add(messageParam);
com.Parameters.Add(blacklistParam);
com.ExecuteNonQuery();
First, use brackets after ToString (it should look like ToString()).
Second. Use Parameterized SQLCommands to protect from SQL Injection Attacks. Instead of
foreach (DecodedShortMessage message in messages) {
com.CommandText = ("INSERT INTO SMSArchives(Message,Blacklist) VALUES ('" +message.ToString + "', 'Yes')");
com.ExecuteNonQuery();
}
use
foreach (DecodedShortMessage message in messages) {
using (SqlCommand command = new SqlCommand("INSERT INTO SMSArchives (Message, Blacklist) VALUES (#par, 'Yes')", , connection)) {
command.Parameters.AddWithValue("#par", message.ToString());
command.ExecuteNonQuery();
}
}

Delete in oracle 10g from asp.net web site - wait on commint?

I need delete data in oracle 10g database from ASP.NET 2.0 web site.
Method DeleteMonthPlan I use on execute delete command. Problem is that this command is executing long time "in browser" and finally delete command is not executed. Maybe it waits on commit? What is root of problem?
This SQL command DELETE C_PPC_PLAN WHERE MFG_MONTH='VALUE' is OK.
MFG_MONTH column type is VARCHAR2(16)
First I need call method DeleteMonthPlan and than I need call InsertDatePlan.
private static void DeleteMonthPlan(string monthIndex)
{
try
{
using (var conn = new OracleConnection(GenerateConnectionString()))
{
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = string.Format("DELETE C_PPC_PLAN WHERE MFG_MONTH='{0}'", monthIndex);
cmd.ExecuteNonQuery();
}
}
catch (Exception exception)
{
throw exception;
}
}
For example this method I use on insert and it is OK.
public void InsertDatePlan(DatePlan dp,
string monthIndex)
{
DeleteMonthPlan(monthIndex);
try
{
using (var conn = new OracleConnection(GenerateConnectionString()))
{
conn.Open();
var cmd = conn.CreateCommand();
cmd.Parameters.Add(":Site", OracleType.VarChar).Value = dp.Site;
cmd.Parameters.Add(":Week", OracleType.VarChar).Value = dp.MfgWeek;
cmd.Parameters.Add(":Month", OracleType.VarChar).Value = dp.MfgMonth;
cmd.Parameters.Add(":Year", OracleType.VarChar).Value = dp.MfgYear;
cmd.Parameters.Add(":Input", OracleType.Number).Value = dp.Input;
cmd.Parameters.Add(":Output", OracleType.Number).Value = dp.Output;
cmd.Parameters.Add(":LMUser", OracleType.VarChar).Value = dp.LmUser;
cmd.Parameters.Add(":PartNo", OracleType.VarChar).Value = dp.PartNo;
cmd.Parameters.Add(":PartNoDesc", OracleType.VarChar).Value = dp.PartNoDesc;
cmd.CommandText = string.Format("INSERT INTO C_PPC_PLAN (CREATE_TIME, SITE, MFG_DAY,MFG_WEEK,MFG_MONTH,MFG_YEAR,INPUT,OUTPUT,LM_TIME,LM_USER,PART_NO,PART_NO_DESC)"
+ " VALUES (to_date('{0}', 'dd-mm-yyyy hh24:mi:ss'), :Site ,to_date('{1}', 'dd-mm-yyyy hh24:mi:ss'),:Week,"
+ ":Month,:Year,:Input,:Output,to_date('{2}', 'dd-mm-yyyy hh24:mi:ss'),:LMUser,:PartNo,:PartNoDesc)"
, dp.CreateTime, dp.MfgDate, dp.LmTime);
cmd.ExecuteNonQuery();
}
}
catch (Exception exception)
{
throw exception;
}
}
I tried use transaction. I call this method on the bottom but is never finish it means that part
trans.Rollback(); or conn.Close(); is never executed.
private static void DeleteMonthPlan(string monthIndex)
{
var conn = new OracleConnection(GenerateConnectionString());
conn.Open();
OracleCommand cmd= conn.CreateCommand();
OracleTransaction trans = conn.BeginTransaction(IsolationLevel.ReadCommitted);
cmd.Transaction = trans;
try
{
cmd.CommandText = "DELETE C_PPC_PLAN WHERE MFG_MONTH='6'";
cmd.ExecuteNonQuery();
trans.Commit();
}
catch (Exception e)
{
trans.Rollback();
}
finally
{
conn.Close();
}
}
try
DELETE FROM C_PPC_PLAN WHERE MFG_MONTH='6'
BTW your code uses "literals" in some places instead of bind variables (params) which makes it vulnerable to SQL injection which is a really serious security problem!

SQL delete command?

I am having trouble with a simple DELETE statement in SQL with unexpected results , it seems to add the word to the list??. Must be something silly!. but i cannot see it , tried it a few different ways. All the same result so quite confused.
public void IncludeWord(string word)
{
// Add selected word to exclude list
SqlConnection conn = new SqlConnection();
String ConnectionString = "Data Source = dev\\SQLEXPRESS ;" + "Initial Catalog=sml;" + "User id=** ;" + "Password =*;" + "Trusted_Connection=No";
using (SqlConnection sc = new SqlConnection(ConnectionString))
{
try
{
sc.Open();
SqlCommand Command = new SqlCommand(
"DELETE FROM excludes WHERE word='#word'" +
conn);
Command.Parameters.AddWithValue("#word", word);
Command.ExecuteNonQuery();
}
catch (Exception e)
{
Box.Text = "SQL error" + e;
}
finally
{
sc.Close();
}
ExcludeTxtbox.Text = "";
Box.Text = " Word : " + word + " has been removed from the Exclude List";
ExcludeLstBox.AppendDataBoundItems = false;
ExcludeLstBox.DataBind();
}
Try removing the single quotes. Also why are you concatenating your SQL string with a connection object (.. word='#word'" + conn)???
Try like this:
try
{
using (var sc = new SqlConnection(ConnectionString))
using (var cmd = sc.CreateCommand())
{
sc.Open();
cmd.CommandText = "DELETE FROM excludes WHERE word = #word";
cmd.Parameters.AddWithValue("#word", word);
cmd.ExecuteNonQuery();
}
}
catch (Exception e)
{
Box.Text = "SQL error" + e;
}
...
Notice also that because the connection is wrapped in a using block you don't need to Close it in a finally statement. The Dispose method will automatically call the .Close method which will return the connection to the ADO.NET connection pool so that it can be reused.
Another remark is that this IncludeWord method does far to many things. It sends SQL queries to delete records, it updates some textboxes on the GUI and it binds some lists => methods like this should be split in separate so that each method has its own specific responsibility. Otherwise this code is simply a nightmare in terms of maintenance. I would very strongly recommend you to write methods that do only a single specific task, otherwise the code quickly becomes a complete mess.
SqlCommand Command = new SqlCommand(
"DELETE FROM excludes WHERE word='#word'" +
conn);
should be replaced with
SqlCommand Command = new SqlCommand(
"DELETE FROM excludes WHERE word='#word'",
conn);
Also try by removing single quotes as suggested by others like this
SqlCommand Command = new SqlCommand(
"DELETE FROM excludes WHERE word=#word",
conn);
The #Word should not be in quotes in the sql query.
Not sure why you're trying to add the connection on the end of the sql query either.
To debug this, examine the CommandText on the SqlCommand object. Before reading further, you should try this.
The issue comes with adding the single quotes around a string that is parameterized. Remove the single quotes and life is beautiful. :-)
Oh, and your conn is an object and needs a comma, not a +.
See the code below:
private void button4_Click(object sender, EventArgs e)
{
String st = "DELETE FROM supplier WHERE supplier_id =" + textBox1.Text;
SqlCommand sqlcom = new SqlCommand(st, myConnection);
try
{
sqlcom.ExecuteNonQuery();
MessageBox.Show("delete successful");
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
}
private void button6_Click(object sender, EventArgs e)
{
String st = "SELECT * FROM supplier";
SqlCommand sqlcom = new SqlCommand(st, myConnection);
try
{
sqlcom.ExecuteNonQuery();
SqlDataReader reader = sqlcom.ExecuteReader();
DataTable datatable = new DataTable();
datatable.Load(reader);
dataGridView1.DataSource = datatable;
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
}
See the code below:
String queryForUpdateCustomer = "UPDATE customer SET cbalance=#txtcustomerblnc WHERE cname='" + searchLookUpEdit1.Text + "'";
try
{
using (SqlCommand command = new SqlCommand(queryForUpdateCustomer, con))
{
command.Parameters.AddWithValue("#txtcustomerblnc", txtcustomerblnc.Text);
con.Open();
int result = command.ExecuteNonQuery();
// Check Error
if (result < 0)
MessageBox.Show("Error");
MessageBox.Show("Record Update of Customer...!", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
con.Close();
loader();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
con.Close();
}
You can also try the following if you don't have access to some of the functionality prescribed above (due, I believe, to older versions of software):
using (var connection = _sqlDbContext.CreatSqlConnection())
{
using (var sqlCommand = _sqlDbContext.CreateSqlCommand())
{
sqlCommand.Connection = connection;
sqlCommand.CommandText = $"DELETE FROM excludes WHERE word = #word";
sqlCommand.Parameters.Add(
_sqlDbContext.CreateParameterWithValue(sqlCommand, "#word", word));
connection.Open();
sqlCommand.ExecuteNonQuery();
}
}
...
I'm an associate dev. Hence the "I believe" above.

Categories

Resources