how to execute SQL with if condition in c# - c#

how to execute SQL with if condition in c#?
This is my query and went i execute this query i get an error saying "Invalid SQL statement; expected 'DELETE', 'INSERT', 'PROCEDURE', 'SELECT', or 'UPDATE'."
I m using MS ACCESS as back end
mycon.ConnectionString = ConnString;
mycon.Open();
string mySelectQuery = "IF (EXISTS (SELECT * FROM Employee AS t1 WHERE t1.ssn ='"+textBox4.Text+"' "+
"))begin UPDATE Employee SET "+
"fname ='"+textBox1.Text+"' ,"+
"minit ='"+textBox2.Text+"' ," +
"lname ='" + textBox3.Text+"', " +
"ssn ='" +textBox4.Text+"', " +
"bdate ='" +textBox5.Text+"', " +
"address ='" +textBox6.Text+"', " +
"sex ='" +textBox7.Text+ "', " +
"salary ='" +textBox8.Text+"', " +
"superssn ='" +textBox9.Text+"', " +
"dno ='" +comboBox2.Text+"'" +
" WHERE ssn = '"+textBox4.Text+"' "+
"end "+
"else "+
" begin "+
" INSERT INTO employee values ('"+textBox1.Text+"','"+textBox2.Text+"','"+textBox3.Text+"','"+textBox4.Text+"','"+textBox5.Text+"','"+textBox6.Text+"','"+textBox7.Text+"','"+textBox8.Text+"','"+textBox9.Text+"','"+comboBox2.Text+"')"+
" end";
OleDbCommand myCommand = new OleDbCommand(mySelectQuery, mycon);
int Success= myCommand.ExecuteNonQuery();

MS Access doesn't support the IF statement. Nor else or begin. You'll have to do this in your C# code, such as performing your "SELECT * FROM Employee AS t1 WHERE t1.ssn ='"+textBox4.Text + "'"; query first and then performing the next one if there are results.
Also, you should either use a parameterized queries or escape the values of you text boxes.

Seems like what you want to happen is UPDATE a record if it Exists in database, else INSERT a record.
You can't do this in one query, so prepare a query for a look-up in database if the record exists, then use the output (isExists or not) to UPDATE or INSERT

Related

Get RecordId from table

I am new to SQL, I have table with RecordId that is incremented automatically and is primary key. I would like to get RecordId of the row that was inserted into table.
Thanks in advance for help.
myCommand.CommandText = "INSERT INTO " + tableName + " (DateRaised,RaisedBy,WeekNo,Platform,Department,Site,Process, Area,NavErrorNo,RootCauseDescription,Status) " +
"VALUES ('" + currentDate.ToString(format) + "','" +
sender + "'," +
weekNumber + ",'" +
comboBoxPlatform.SelectedItem + "','" +
comboBoxDepartment.SelectedItem + "','" +
comboBoxSite.SelectedItem + "','" +
comboBoxProcess.SelectedItem + "','" +
comboBoxArea.SelectedItem + "','" +
textBoxNavError.Text + "','" +
textBoxIssue.Text + "','Open')";
//int lastInsertedId =
myCommand.ExecuteNonQuery();
lastInsertedId should be int from RecordId in my table.
To do this properly (if this is for SQL Server - you weren't very clear on this), I see two options:
Approach #1 - using SCOPE_IDENTITY
This works well if you're only ever inserting a single row at a time - use something like this:
// set up your query using *PARAMETERS** as you **ALWAYS** should!
// Using SELECT SCOPE_IDENTITY() to get back the newly inserted "Id"
myCommand.CommandText = "INSERT INTO dbo.SomeTable (list-of-columns) " +
"VALUES (#param1, #param2, #param3, ...., #paramN); " +
"SELECT SCOPE_IDENTITY();";
// set up the parameters and theirs values
object result = myCommand.ExecuteScalar();
if (result != null)
{
int lastInsertedId = Convert.ToInt32(result);
}
Approach #2 - using the OUTPUT clause
This works well even if you insert multiple rows at once (typically using a SELECT after the INSERT):
// set up your query using *PARAMETERS** as you **ALWAYS** should!
// Using SELECT SCOPE_IDENTITY() to get back the newly inserted "Id"
myCommand.CommandText = "INSERT INTO dbo.SomeTable (list-of-columns) " +
"OUTPUT Inserted.RecordId " +
"VALUES (#param1, #param2, #param3, ...., #paramN); ";
// set up the parameters and theirs values
object result = myCommand.ExecuteScalar();
if (result != null)
{
int lastInsertedId = Convert.ToInt32(result);
}
First thing this is not a good idea to call direct SQL statement from code it can cause an issue for SQL injection as #Zohar suggested.
You can either user parametrized query or sp.
Inside sp, you can use
SELECT ##IDENTITY AS 'Identity';
after Insert statement, it will return the last auto-incremented value for PK,
then return this value as an output parameter and catch it after .ExecuteNonQuery(); in C# code.
This should do the trick for You
private void SelectLast()
{
string sqlLast = "SELECT TOP(1) RecordId FROM [YourtableName] ORDER BY 1 DESC";
Connection.Open();
using (SqlCommand cmd = new SqlCommand(sqlLast, Connection))
{
cmd.CommandType = CommandType.Text;
{
int insertedID = Convert.ToInt32(cmdAdd.ExecuteScalar());
textBoxID.Text = Convert.ToString(insertedID);
}
Connection.Close();
}
}

Data is not saved in SQL Server table [duplicate]

This question already has answers here:
SQL update statement in C#
(10 answers)
Closed 5 years ago.
enter image description here
I am trying to update data in a SQL Server table. I get a message that data is saved, after a query execution.
But when I check in that table, I find that the data is not saved. Is anything wrong in my query?
I am using SQL Server 2008 and C# for coding.
SqlCommand cmd1 = new SqlCommand("UPDATE Inward_Rpt SET Date='" + date + "',Cashier_Name='" + cashier_name + "',Supplier_Code='" + sup_code + "',Supplier_Name='" + name + "',Payment_Mode ='" + p_method + "',Total_Bill='" + tot_bill + "',Total_Paid='" + tot_paid + "',Previous_Due = '" + total_due + "',Current_Due ='" + c_due + "',Remark ='" + remark + "'WHERE Supplier_Name='" + name + "'", con);
cmd1.ExecuteNonQuery();
MessageBox.Show("Data Saved..");
I think I found your error. Your WHERE clause is using the same name that you are updating the Supplier Name to. Assuming this is a new name, you will never find the record you want to update. The below code is cleaner, not prone to injection issues, and it should work the way you want.
Note that you will have to provide a new variable to cater to the name / sup_name situation.
SqlCommand cmd1 = new SqlCommand();
cmd1.Connection = con;
cmd1.CommandText = #"
UPDATE Inward_Rpt
SET Date = #date
, Cashier_Name = #cashier_name
, Supplier_Code = #sup_code
, Supplier_Name = #sup_name
, Payment_Mode = #p_method
, Total_Bill = #tot_bill
, Total_Paid = #tot_paid
, Previous_Due #total_due
, Current_Due = #c_due
, Remark = #remark
WHERE Supplier_Name = #name";
cmd1.Parameters.AddWithValue("#date", date);
cmd1.Parameters.AddWithValue("#cashier_name", cashier_name);
cmd1.Parameters.AddWithValue("#sup_code", sup_code);
cmd1.Parameters.AddWithValue("#sup_name", sup_name);
cmd1.Parameters.AddWithValue("#p_method", p_method);
cmd1.Parameters.AddWithValue("#tot_bill", tot_bill_name);
cmd1.Parameters.AddWithValue("#tot_paid", tot_paid);
cmd1.Parameters.AddWithValue("#total_due", total_due);
cmd1.Parameters.AddWithValue("#c_due", c_due);
cmd1.Parameters.AddWithValue("#remark", remark);
cmd1.Parameters.AddWithValue("#name", name);
cmd1.ExecuteNonQuery();
MessageBox.Show("Data Saved..");
Is the All the Fields are String Datatype in your Database Table? Check the Datatypes Because u give Single Quotes for all Data. If the Table Datatype is Number Remove the Single Quotes.
SqlCommand cmd1 = new SqlCommand("UPDATE Inward_Rpt SET Date='" + date + "',Cashier_Name='" + cashier_name + "',Supplier_Code=" + sup_code + ",Supplier_Name='" + name + "',Payment_Mode ='" + p_method + "',Total_Bill='" + tot_bill + "',Total_Paid='" + tot_paid + "',Previous_Due = '" + total_due + "',Current_Due ='" + c_due + "',Remark ='" + remark + "'WHERE Supplier_Name='" + name + "'", con);

Syntax error in INSERT INTO statement MS access (not keyword issue)

I am facing this error when I try to insert a data row in to table in ms access file.
dataTable is table I got using select * from TableName,
I got it, displayed it, made changes, now I want to replace previous one with new one. So I am going to delete all previous rows and add each row one by one from new table. But I am not able to insert any row.
I am getting this error
"Syntax error in INSERT INTO statement."
String query = "INSERT INTO [" + TableName + "] (TaskID, HTMLTopic, [Group], nKey,"
+ " nText, nImage, nSelImage, nFontName, nFontInfo, Keywords) VALUES (#TaskID,"
+ " #HTMLTopic, #Group, #nKey, #nText, #nImage, #nSelImage, #nFontName, "
+ " #nFontInfo, #Keywords)";
OleDbCommand command = new OleDbCommand(query, mdbConnection);
command.Parameters.AddWithValue("#TaskID", dataTable.Rows[0]["TaskID"]);
command.Parameters.AddWithValue("#HTMLTopic", dataTable.Rows[0]["HTMLTopic"]);
command.Parameters.AddWithValue("#Group", dataTable.Rows[0]["Group"]);
command.Parameters.AddWithValue("#nKey", dataTable.Rows[0]["nKey"]);
command.Parameters.AddWithValue("#nText", dataTable.Rows[0]["nText"]);
command.Parameters.AddWithValue("#nImage", dataTable.Rows[0]["nImage"]);
command.Parameters.AddWithValue("#nSelImage", dataTable.Rows[0]["nSelImage"]);
command.Parameters.AddWithValue("#nFontName", dataTable.Rows[0]["nFontName"]);
command.Parameters.AddWithValue("#nFontInfo", dataTable.Rows[0]["nFontInfo"]);
command.Parameters.AddWithValue("#Keywords", dataTable.Rows[0]["Keywords"]);
mdbConnection.Open();
command.ExecuteNonQuery();
mdbConnection.Close();
Edit:
Changed it just for debugging to
String query = "INSERT INTO [" + TableName + "] (TaskID, HTMLTopic, nRelative, [Group], nKey,"
+ " nText, nImage, nSelImage, nFontName, nFontInfo, Keywords) VALUES ('" + dataTable.Rows[0]["TaskID"]
+ "', '" + dataTable.Rows[0]["HTMLTopic"] + "', '" + dataTable.Rows[0]["nRelative"] + "', '" + dataTable.Rows[0]["Group"]
+ "', " + dataTable.Rows[0]["nKey"] + ", '" + dataTable.Rows[0]["nText"] + "', '" + dataTable.Rows[0]["nImage"]
+ "', '" + dataTable.Rows[0]["nSelImage"] + "', '" + dataTable.Rows[0]["nFontName"] + "', '" + dataTable.Rows[0]["nFontInfo"]
+ "', '" + dataTable.Rows[0]["Keywords"] + "')";
OleDbCommand command = new OleDbCommand(query, mdbConnection);
Debug.Print(command.CommandText);
mdbConnection.Open();
command.ExecuteNonQuery();
mdbConnection.Close();
I added some single quotes so database can understand them as string.
There looks to be a bug somewhere between the provider and the engine. It looks like the issue is with your column named nText.
I duplicated your schema in an Access 2013 db and received the same error that you did. I then started making various changes to the column names and the query. When I changed column names (appending a X to the end of each column) the INSERT worked. I then went back and started adding square brackets to other columns names. As soon as I did that for nText it worked. This query works for me in a C# console app using the Microsoft.ACE.OLEDB.12.0 oldeb provider:
String query =
"INSERT INTO [" + TableName + "] (TaskID,HTMLTopic,[Group],nKey,[nText],nImage,nSelImage,nFontName,nFontInfo,Keywords)" +
"VALUES" +
"(#TaskID,#HTMLTopic, #Group, #nKey, #nText, #nImage, #nSelImage, #nFontName,#nFontInfo, #Keywords)"
I agree with you that it shouldn't be a keyword / reserved word issue, but it sure acts like it is. NTEXT is a keyword in TSQL (SQL Server), but not Access according to https://support.microsoft.com/en-us/kb/286335.

A column named "MYTEST" is generated automatically in my sql server database

I have a winforms project in which I add a table from sql server database into a Datagridview.
I don't know why a column named "MYTEST" is generated automatically in my sql server DB when I make changes like updating the table in the database/updating the datagridview.
I have to say that there are lots of sql queries in my project but none of them include "INSERT".
EDIT
Here are the queries:
sql1 = "select CONVERT(Bit,SwActive) AS SwActive, Kod AS Kod ,Nm AS Nm,(CONVERT(char,FromDate,103)) AS FromDate, (CONVERT(char,ToDate,103)) AS ToDate " +
"FROM Mivza " +
"ORDER BY SwActive DESC";
sqlupdate= "update Mivza set SwActive='" + SwActive + "',MivzaButal='" + MivzaButal + "' " +
"where Kod='" + Kod + "'";
sqlsearch = "select max(isnull(SwActive,0)) as SwActive, max(Mivza.Kod) as Kod, max(Mivza.Nm) as Nm, isnull(Max(convert(char,FromDate,103)), '') as FromDate, isnull(max(convert(char,ToDate,103)),'') as ToDate, Mivza.C as C, max(DateDiff(m,0,FromDate)) as DDF, max(DateDiff(m,0,ToDate)) as DDT " +
"from Mivza " +
"left join Mivza_Prt_All on Mivza_Prt_All.Mivza = Mivza.C " +
"left join Prt on Prt.C = Mivza_Prt_All.Prt " +
"where DateBitul is null and isnull(Mivza.Nm,'') like '%h%' or isnull(Prt.Nm,'') like '%h%' " +
"group by Mivza.C " +
"ORDER BY SwActive DESC, Kod ASC";

SQL Update Statement Does Nothing

I have a SQL Update statement that when run in VS2010 via the new query window works, but when I structure it as an update statement nothing happens.
I was wondering if someone can see what I'm doing wrong? Like I said the code works when executed via the query window in VS2010.
Here's my code:
SqlConnection connection = new SqlConnection(DBConnection.GetConnection().ConnectionString);
string updateStatement =
"DECLARE #OldParent hierarchyid, #NewParent hierarchyid " +
"SELECT #OldParent = Hierarchy FROM SpecProducts " +
"WHERE ID = #NodeToMoveID ; ------ top item to be moved " +
"SELECT #NewParent = Hierarchy FROM SpecProducts " +
"WHERE ID = #NodeToMoveIntoID ; -- ID of item to move into - new parent " +
"DECLARE children_cursor CURSOR FOR " +
"SELECT Hierarchy FROM SpecProducts " +
"WHERE Hierarchy = #OldParent; " +
"DECLARE #ChildId hierarchyid; " +
"OPEN children_cursor " +
"FETCH NEXT FROM children_cursor INTO #ChildId; " +
"WHILE ##FETCH_STATUS = 0 " +
"BEGIN " +
"START: " +
"DECLARE #NewId hierarchyid; " +
"SELECT #NewId = #NewParent.GetDescendant(MAX(Hierarchy), NULL) " +
"FROM SpecProducts WHERE Hierarchy.GetAncestor(1) = #NewParent; " +
"UPDATE SpecProducts " +
"SET Hierarchy = Hierarchy.GetReparentedValue(#ChildId, #NewId), " +
"MovedToDate = #MovedToDate, " +
"MovedToBy = #MovedToBy " +
"WHERE Hierarchy.IsDescendantOf(#ChildId) = 1; " +
"IF ##error <> 0 GOTO START -- On error, retry " +
"FETCH NEXT FROM children_cursor INTO #ChildId; " +
"END " +
"CLOSE children_cursor; " +
"DEALLOCATE children_cursor;";
SqlCommand updateCommand = new SqlCommand(updateStatement, connection);
updateCommand.Parameters.AddWithValue("#NodeToMoveID", nodeIDToMove);
updateCommand.Parameters.AddWithValue("#NodeToMoveIntoID", newParentID);
updateCommand.Parameters.AddWithValue("#MovedToDate", DateTime.Now);
updateCommand.Parameters.AddWithValue("#MovedToBy", userModifying.ID);
try
{
connection.Open();
updateCommand.ExecuteNonQuery();
return true;
}
One thing to point out is that when my code executes in VS2010 Query window, I get a warning about the 'Declare' feature, but I press continue and it works. Does my statement not working have anything to do with the Declare features?
Any thoughts/solutions would be greatly appreciated.
Many thanks.
Rob
I am adding this as an answer since the comment discussion was getting a bit long.
According to the documentation, ExecuteNonQuery returns -1 when there is a database rollback. This is likely related to the error you gave:
Error source: .net.sqlclient data provider
Error message: Must declare the scalar variabe NodeToMoveID & NodeToMoveIntoID & MovedToDate.
As you mentioned, you were having issues using the SQL parameters. One solution to this is to replace those parameters with variables in updateStatement.
Another thing you could try is using a stored procedure and changing those parameters, although that may not work for some reason either.

Categories

Resources