I have been searching around and I am either confusing myself or not searching for the right thing.
I have this data reader that pulls some information for a store procedure.. but I don't think I am doing it right.
string constr = ConfigurationManager.ConnectionStrings["PAYROLL"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand("DLI_EMPLOYEE_PORTAL_EMPLOYEE_INFORMATION"))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#EID", Session["sessionEMPID"].ToString());
cmd.Connection = con;
con.Open();
SqlDataReader dataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
while (dataReader.Read())
{
string EMP_FIRST = dataReader["FIRST_NAME"].ToString();
string EMP_LAST = dataReader["LAST_NAME"].ToString();
string EMP_DEPT = dataReader["DEPT"].ToString();
string EMP_DEPT_ID = dataReader["DEPT_ID"].ToString();
body = body + "<p>SUBMITTED BY : (" + Session["sessionEMPID"].ToString() + ") " + EMP_FIRST + " " + EMP_LAST + " - DEPT : " + EMP_DEPT + "</p> " + System.Environment.NewLine;
}
con.Close();
}
}
I just need to query one row based of an employee ID.. and I would rather do it not by stored procedure but a select query.
SELECT e.FIRST_NAME, e.LAST_NAME, e.DEPT_ID, d.NAME
FROM EMPLOYEE AS e
INNER JOIN DEPARTMENT AS d ON e.DEPT_ID = d.ID
WHERE (e.ID = 'sim01')
I am building an HTML body string so that is why I need the information.
body = body + "<p>SUBMITTED BY : (" + Session["sessionEMPID"].ToString() + ") " + EMP_FIRST + " " + EMP_LAST + " - DEPT : " + EMP_DEPT + "</p> " + System.Environment.NewLine;
Any help is greatly appreciated. Thank you.
If all you want to do is use a query instead of a stored procedure, just pass your SQL statement to the Command and set your CommandType to Text. If you only ever expect one row, use if (dataReader.Read() instead of while (dataReader.Read()).
string constr = ConfigurationManager.ConnectionStrings["PAYROLL"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand(
"SELECT e.FIRST_NAME, e.LAST_NAME, e.DEPT_ID, d.NAME " +
"FROM EMPLOYEE AS e " +
"INNER JOIN DEPARTMENT AS d ON e.DEPT_ID = d.ID " +
"WHERE (e.ID = #EID)"));
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#EID", Session["sessionEMPID"].ToString());
cmd.Connection = con;
con.Open();
SqlDataReader dataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
if (dataReader.Read())
{
string EMP_FIRST = dataReader["FIRST_NAME"].ToString();
string EMP_LAST = dataReader["LAST_NAME"].ToString();
string EMP_DEPT = dataReader["DEPT"].ToString();
string EMP_DEPT_ID = dataReader["DEPT_ID"].ToString();
body = body + "<p>SUBMITTED BY : (" + Session["sessionEMPID"].ToString() + ") " + EMP_FIRST + " " + EMP_LAST + " - DEPT : " + EMP_DEPT + "</p> " + System.Environment.NewLine;
}
con.Close();
}
}
If the query can return more than one row, you can add TOP 1 to the query with an ORDER BY <some other field> to grab only the most relevant one.
It us better to use query instead of stored procedure if there is no TSQL logic
SQL1 portion works just fine, but I need help figuring out if my statements in SQL2, 3 & 4 are correct because it currently doesn't work. I want to insert 'Audience View 1' in VIEW if the words 'Camera 1' is present in VIDEOPATH, 'Audience View 2' in VIEW if the words 'Camera 2' is present in VIDEOPATH and so on.
string[] files = Directory.GetFiles("C:/Users/sit/Videos/Done/");
string view1 = "Audience View 1";
string view2 = "Audience View 2";
string view3 = "Lecturer View";
foreach (string file in files) {
string SQL1 = "INSERT INTO TBL_LESSONCAM(VIDEOPATH)VALUES('" + (file) + "')";
string SQL2 = "UPDATE TBL_LESSONCAM(VIEW)VALUES('" + (view1) + "')" + "WHERE VIDEOPATH LIKE '%Camera 1%'";
string SQL3 = "UPDATE TBL_LESSONCAM(VIEW)VALUES('" + (view2) + "')" + "WHERE VIDEOPATH LIKE '%Camera 2%'";
string SQL4 = "UPDATE TBL_LESSONCAM(VIEW)VALUES('" + (view3) + "')" + "WHERE VIDEOPATH LIKE '%Camera 3%'";
SqlCommand cmd = new SqlCommand();
cmd.Connection = cn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = SQL1;
cmd.CommandText = SQL2;
cmd.CommandText = SQL3;
cmd.CommandText = SQL4;
cn.Open();
cmd.ExecuteNonQuery();
cn.Close();
}
UPDATE: Is my structure for running multiple SQL statements correct?
your update:
string SQL2 = "UPDATE TBL_LESSONCAM(VIEW)VALUES('" + (view1) + "')" + "WHERE VIDEOPATH LIKE '%Camera 1%'";
should be
string SQL2 = "UPDATE TBL_LESSONCAM set view = '" + (view1) + "'" + " WHERE VIDEOPATH LIKE '%Camera 1%'; ";
Please have a look at What are good ways to prevent SQL injection?
I had the following implementation of filling a DataTable with SQL:
var con = new SqlConnection();
var cmd = new SqlCommand();
var dt = new DataTable();
string sSQL = #"SELECT LogID, Severity, Title
FROM dbo.Log
WHERE UPPER(LogID) LIKE '%" + searchPhrase.ToUpper() + #"%' OR UPPER(Severity) LIKE '%" + searchPhrase.ToUpper() + #"%' OR UPPER(Title) LIKE '%" + searchPhrase.ToUpper() + #"%' ORDER BY " + orderBy + " " + orderFrom + #"
OFFSET ((" + (Convert.ToInt32(current) - 1).ToString() + ") * " + rowCount + #") ROWS
FETCH NEXT " + rowCount + " ROWS ONLY;";
try
{
using (var connection = THF.Models.SQLConnectionManager.GetConnection())
{
using (var command = new SqlCommand(sSQL, connection))
{
connection.Open();
command.CommandTimeout = 0;
var da = new SqlDataAdapter(command);
da.Fill(dt);
}
}
}
catch { }
This works nicely but I've realized that this is dangerous due to SQL Injection. So I've tried to solve that danger using parameterized queries like this:
var con = new SqlConnection();
var cmd = new SqlCommand();
var dt = new DataTable();
cmd.Parameters.Add(new ObjectParameter("#searchPhrase", searchPhrase.ToUpper()));
cmd.Parameters.Add(new ObjectParameter("#orderBy", orderBy));
cmd.Parameters.Add(new ObjectParameter("#orderFrom", orderFrom));
cmd.Parameters.Add(new ObjectParameter("#current", current));
cmd.Parameters.Add(new ObjectParameter("#rowCount", rowCount));
string sSQL = #"SELECT LogID, Severity, Title
FROM dbo.Log
WHERE UPPER(LogID) LIKE '%" + searchPhrase.ToUpper() + #"%' OR UPPER(Severity) LIKE '%" + searchPhrase.ToUpper() + #"%' OR UPPER(Title) LIKE '%" + searchPhrase.ToUpper() + #"%' ORDER BY " + orderBy + " " + orderFrom + #"
OFFSET ((" + (Convert.ToInt32(current) - 1).ToString() + ") * " + rowCount + #") ROWS
FETCH NEXT " + rowCount + " ROWS ONLY;";
try
{
using (var connection = THF.Models.SQLConnectionManager.GetConnection())
{
using (var command = new SqlCommand(sSQL, connection))
{
connection.Open();
command.CommandTimeout = 0;
var da = new SqlDataAdapter(command);
da.Fill(dt);
}
}
}
catch { }
Unfortunately now my data table doesn't fill. What am I doing wrong?
You are using multiple command and connection references, not sure if thats a copy/paste problem or your actual code is like that. In the second case it will not even compile.
Reference the parameters directly in your query, see below. Sql Server uses named parameters so the same parameter can be reused in multiple locations.
Desc/Asc cannot be used as a parameter. You should double check the value though or use an enum and pass that (recommended).
The same is true of the numeric values for rowcount, pass those in as numbers or check their values using a TryParse to ensure it is numeric and not malicious code.
The default install options for Sql Server is for a case insensitive coalition. This means you do not have to UPPER a string to do a comparison. If you do have a case sensitive install then do not change this, otherwise remove all calls to UPPER when doing comparisons.
Finally you well never know why your code is not working if you surround your code in try/catch and have an empty catch block. Your code will fail silently and you will be left scratching your head. Do not do this anywhere in your code, it is bad practice!! Either catch the exception and handle it (do something so code can recover) OR log it and rethrow using throw; OR do not catch it at all. I chose the later and removed it.
Code
var currentNum = Convert.ToInt32(current) - 1;
var temp = 0;
if(!"desc".Equals(orderFrom, StringComparison.OrdinalIgnoreCase) && !"asc".Equals(orderFrom, StringComparison.OrdinalIgnoreCase))
throw new ArgumentException("orderFrom is not a valid value");
if(!int.TryParse(rowCount, out temp))
throw new ArgumentException("Rowcount is not a valid number");
var dt = new DataTable();
string sSQL = #"SELECT LogID, Severity, Title
FROM dbo.Log
WHERE UPPER(LogID) LIKE #searchPhrase
OR UPPER(Severity) LIKE #searchPhrase
OR UPPER(Title) LIKE #searchPhrase
ORDER BY #orderBy " + orderFrom + "
OFFSET ((" + currentNum.ToString() + ") * " + rowCount + #") ROWS
FETCH NEXT " + rowCount + " ROWS ONLY;";
using (var connection = THF.Models.SQLConnectionManager.GetConnection())
using (var command = new SqlCommand(sSQL, connection))
{
cmd.Parameters.Add(new SqlParameter("#searchPhrase", "%" + searchPhrase.ToUpper() + "%"));
cmd.Parameters.Add(new SqlParameter("#orderBy", orderBy));
connection.Open();
command.CommandTimeout = 0;
var da = new SqlDataAdapter(command);
da.Fill(dt);
}
Here is a simple example of how this should be done.
con.Open();
SqlCommand cmd = new SqlCommand(#"insert into tbl_insert values(#name,#email,#add)", con);
cmd.Parameters.AddWithValue("#name", txtname.Text);
cmd.Parameters.AddWithValue("#email", txtemail.Text);
cmd.Parameters.AddWithValue("#add", txtadd.Text);
cmd.ExecuteNonQuery();
con.Close();
I have declared the scalar already but I am still getting the error. My code checks to see if an entry exists, if it does it updates the entry or if it does not exist it creates a new entry:
try
{
string server = Properties.Settings.Default.SQLServer;
string connection = "Data Source=" + server + ";Initial Catalog=Propsys;Persist Security Info=True;User ID=sa;Password=0925greg";
using (SqlConnection cn = new SqlConnection(connection))
{
cn.Open();
SqlCommand cmdCount = new SqlCommand("SELECT count(*) from Agent WHERE ContactPerson = #" + this.contactPersonTextBox.Text, cn);
cmdCount.Parameters.AddWithValue("#ContactPerson", contactPersonTextBox.Text);
SqlDataReader myReader;
myReader = cmdCount.ExecuteReader();
int count = 0;
while (myReader.Read())
{
count = count + 1;
}
if (count > 0)
{
string query = "UPDATE _1Agent SET DealID = #DealID, \n" +
"ContactPerson = #ContactPerson, \n" +
"Address = #Address, \n" +
"TaxVatNo = #TaxVatNo, \n" +
"Comm = #Comm, \n" +
"WorkTel = #WorkTel, \n" +
"Cell = #Cell, \n" +
"Fax = #Fax, \n" +
"Email = #Email, \n" +
"Web = #Web, \n" +
"CreateDate = #CreateDate, \n" +
"Notes = #Notes WHERE id = #id";
SqlCommand cm = new SqlCommand(query);
string Contact = contactPersonTextBox.Text;
cm.Parameters.AddWithValue("#DealID", txtDealNo.Text);
cm.Parameters.AddWithValue("#ContactPerson", contactPersonTextBox.Text);
cm.Parameters.AddWithValue("#Address", addressTextBox.Text);
cm.Parameters.AddWithValue("#TaxVatNo", taxVatNoTextBox.Text);
cm.Parameters.AddWithValue("#Comm", commTextBox.Text);
cm.Parameters.AddWithValue("#WorkTel", workTelTextBox.Text);
cm.Parameters.AddWithValue("#Cell", cellTextBox.Text);
cm.Parameters.AddWithValue("#Fax", faxTextBox.Text);
cm.Parameters.AddWithValue("#Email", emailTextBox.Text);
cm.Parameters.AddWithValue("#CreateDate", DateTime.Now);
cm.Parameters.AddWithValue("#Notes", notesTextBox.Text);
cm.CommandText = query;
cm.ExecuteNonQuery();
cn.Close();
MessageBox.Show("Saved...", "Data Saved", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
}
else
{
string query1 = "INSERT INTO _1Agent (DealID, \n" +
"ContactPerson, \n" +
"Address, \n" +
"TaxVatNo, \n" +
"Comm, \n" +
"WorkTel, \n" +
"Cell, \n" +
"Fax, \n" +
"Email, \n" +
"CreateDate, \n" +
"Notes) VALUES ('" + txtDealNo.Text + "',\n" +
"'" + contactPersonTextBox.Text + "',\n" +
"'" + addressTextBox.Text + "',\n" +
"'" + taxVatNoTextBox.Text + "',\n" +
"'" + commTextBox.Text + "',\n" +
"'" + workTelTextBox.Text + "',\n" +
"'" + cellTextBox.Text + "',\n" +
"'" + faxTextBox.Text + "',\n" +
"'" + emailTextBox.Text + "',\n" +
"'" + notesTextBox.Text + "',\n" +
"'" + DateTime.Now + "')";
SqlCommand cm = new SqlCommand(query1);
string Contact = contactPersonTextBox.Text;
cm.Parameters.AddWithValue("#DealID", txtDealNo.Text);
cm.Parameters.AddWithValue("#ContactPerson", contactPersonTextBox.Text);
cm.Parameters.AddWithValue("#Address", addressTextBox.Text);
cm.Parameters.AddWithValue("#TaxVatNo", taxVatNoTextBox.Text);
cm.Parameters.AddWithValue("#Comm", commTextBox.Text);
cm.Parameters.AddWithValue("#WorkTel", workTelTextBox.Text);
cm.Parameters.AddWithValue("#Cell", cellTextBox.Text);
cm.Parameters.AddWithValue("#Fax", faxTextBox.Text);
cm.Parameters.AddWithValue("#Email", emailTextBox.Text);
cm.Parameters.AddWithValue("#CreateDate", DateTime.Now);
cm.Parameters.AddWithValue("#Notes", notesTextBox.Text);
cm.CommandText = query1;
cm.ExecuteNonQuery();
cn.Close();
MessageBox.Show("Saved...", "Data Saved", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
Your usage of parameter is wrong, it should be:
SqlCommand cmdCount =
new SqlCommand("SELECT count(*) from Agent WHERE ContactPerson = #ContactPerson", cn);
Later you are adding the parameter correctly.
cmdCount.Parameters.AddWithValue("#ContactPerson", contactPersonTextBox.Text);
To get the count use SqlCommand.ExecuteScalar, instead of using DataReader:
int count = (int) cmdCount.ExecuteScalar();
For the other queries, UPDATE and INSERT, you can use a verbatim string, instead of concatenating strings over multiple lines.
string query = #"UPDATE _1Agent SET DealID = #DealID,
ContactPerson = #ContactPerson,
Address = #Address,
TaxVatNo = #TaxVatNo,
Comm = #Comm,
WorkTel = #WorkTel,
Cell = #Cell,
Fax = #Fax,
Email = #Email,
Web = #Web,
CreateDate = #CreateDate,
Notes = #Notes WHERE id = #id";
Other issues with the code:
You are concatenating strings to form INSERT query, later you are adding parameters, follow the same convention as UPDATE query and then use the parameters.
As pointed out in the other answer, you are not adding parameter#id value for UPDATE command
You are not specifying connection property with your UPDATE and INSERT command:
Specify it like
SqlCommand cm = new SqlCommand(query, cn);
Consider enclosing Connection and Command object in using
statement as it will ensure the proper disposal of unmanaged resources.
I see a few things;
Don't use string concatenation with # sign for parameters. That's wrong usage. Use it like;
"SELECT count(*) from Agent WHERE ContactPerson = #ContactPerson"
and
cmdCount.Parameters.AddWithValue("#ContactPerson", contactPersonTextBox.Text);
and use ExecuteScalar to get first column of the first row. Using a reader is unnecessary for this command.
Your UPDATE query requires #id value since you declare it in your command as;
cm.Parameters.AddWithValue("#id", yourIDvalue);
Your INSERT query, you never declare your parameters in your command. You just concatenate them with their values. And use verbatim string literal to generate multiline strings instead of using \n.
Please
Read more carefully about parameterized queries and how you can use them.
Give me parameterized SQL, or give me death
You forget to mention parameter name in your select query
SqlCommand cmdCount = new SqlCommand("SELECT count(*) from Agent WHERE ContactPerson = #ContactPerson", cn);
cmdCount.Parameters.AddWithValue("#ContactPerson", contactPersonTextBox.Text);
There are some wrong things .So you can refer #Soner Gönül and #habib answers
And change your insert query.Since you have declared paramertes but you didn't define.So change as follows
string query1 = "INSERT INTO _1Agent (DealID,ContactPerson,Address,TaxVatNo,
Comm, WorkTel, Cell, Fax, Email,Notes,CreateDate)
VALUES ( #DealID , #ContactPerson,#Address ,#TaxVatNo ,
#Comm,#WorkTel , #Cell,#Fax,#Email,#Notes,#CreateDate)";
I have a button in my windows forms which UPDATES every table. However, I am getting error SQLException was unhandled. Incorrect syntax near '='.
This is my code in Update Button:
public void btnUpdate_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
try
{
//MessageBox.Show(row.Cells[7].FormattedValue.ToString());
System.Data.SqlClient.SqlConnection sqlConnection1 =
new System.Data.SqlClient.SqlConnection("server=Test\\Test; Integrated Security=true; Database=Testing;");
System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = "UPDATE dbo.JobStatus SET ShipTrackingNumber = '" + row.Cells[7].FormattedValue.ToString() + "' WHERE jobtableid = " + row.Cells[5].FormattedValue.ToString();
cmd.CommandText = "UPDATE dbo.JobStatus SET ShipMethodTransmitted = '" + row.Cells[8].FormattedValue.ToString() + "' WHERE jobtableid = " + row.Cells[5].FormattedValue.ToString();
cmd.CommandText = "UPDATE dbo.JobStatus SET DateShipTransmitProcessed = '" + row.Cells[9].FormattedValue.ToString() + "' WHERE jobtableid = " + row.Cells[5].FormattedValue.ToString();
cmd.CommandText = "UPDATE dbo.JobStatus SET ShipmentProcessedBy = '" + row.Cells[10].FormattedValue.ToString() + "' WHERE jobtableid = " + row.Cells[5].FormattedValue.ToString();
cmd.CommandText = "UPDATE dbo.JobStatus SET Critical = '" + row.Cells[11].FormattedValue.ToString() + "' WHERE jobtableid = " + row.Cells[5].FormattedValue.ToString();
cmd.CommandText = "UPDATE dbo.JobStatus SET ShipTransmitStatus = '" + row.Cells[13].FormattedValue.ToString() + "' WHERE jobtableid = " + row.Cells[5].FormattedValue.ToString();
cmd.Connection = sqlConnection1;
sqlConnection1.Open();
cmd.ExecuteNonQuery();
sqlConnection1.Close();
}
catch (Exception e)
{
MessageBox.Show("Update Failed!!!");
}
}
}
Can anyone tell me what is wrong with these statements? Thanks!
Why not simply do it in a single update statement. So something like:
var sql = new StringBuilder();
sql.AppendLine( "UPDATE dbo.JobStatus" );
sql.AppendLine( "Set ShipTrackingNumber = #TrackingNumber" );
sql.AppendLine( ", DateShipTransmitProcessed = #DateShipTransmitProcessed" );
sql.AppendLine( ", ShipmentProcessedBy = #ShipmentProcessedBy" );
sql.AppendLine( ", Critical = #Critical" );
sql.AppendLine( ", ShipTransmitStatus = #ShipTransmitStatus" );
sql.AppendLine( "Where jobtableId = #jobTableId" );
cmd.Connection = sqlConnection1;
cmd.CommandText = sql.ToString();
cmd.Parameters.AddWithValue("#TrackingNumber", row.Cells[7].FormattedValue);
cmd.Parameters.AddWithValue("#DateShipTransmitProcessed", row.Cells[8].FormattedValue);
cmd.Parameters.AddWithValue("#ShipmentProcessedBy", row.Cells[9].FormattedValue);
cmd.Parameters.AddWithValue("#Critical", row.Cells[10].FormattedValue);
cmd.Parameters.AddWithValue("#ShipTransmitStatus", row.Cells[11].FormattedValue);
cmd.Parameters.AddWithValue("#jobTableId", row.Cells[5].FormattedValue);
Aside from what was mentioned in my comment; I don't see anything wrong with the syntax of your SQL. It's quite possible that your FormattedValue has an invalid character like a ' in the string itself, which would lead to a SQL error. Print out the value of the CommandText itself after the string has been built to see what it actually looks like.
Your UPDATE statement is incorrect. UPDATE syntax is:
UPDATE table
SET
column1 = 'value',
column2 = 'value2'
WHERE
condition;
You are overwriting your statement every time you assign to cmd. You probably want something more like:
cmd = "UPDATE table";
cmd += "SET column1 = '" + value + "',";
cmd += "SET column2 = " + intValue;
cmd += "WHERE idRow = '" + rowToUpdateValue + "'";
Also, if this doesn't help, check that you are not trying to check an INT column using a 'char' value.
Please check your conditions thus:
if(row.Cells[5].FormattedValue.ToString())
then execute update query