What is wrong with this MySQL query in C#? - c#

I'm trying to insert multiple rows into a table by building a query by iterating through a list. I'm getting errors for my SQL syntax, it looks like this:
string sql = "insert into achievement(Rank,Event,UserId) values ";
string valueSQL = "";
using (command = new MySqlCommand("begin;" +
" insert into profile(Username,TextInfo) values(#username,#textinfo);" +
" set #userid = LAST_INSERT_ID(); " +
sql +
" insert into social(URL,UserId) values(#url,#userid);" +
" COMMIT;", conn))
{
command.Parameters.AddWithValue("username", dto.Username);
command.Parameters.AddWithValue("textinfo", dto.FreeText);
command.Parameters.AddWithValue("url", dto.SocialURL);
for(int i = 0; i < dto.achievementDTOs.Count; i++)
{
valueSQL += /*(valueSQL == "" ? "": ",") +*/ "(#rank" + i + ",#event" + i + ",#userid)";
command.Parameters.AddWithValue("rank"+i, dto.achievementDTOs[i].Rank);
command.Parameters.AddWithValue("event"+i, dto.achievementDTOs[i].Event);
}
sql += valueSQL;
sql += ";";
command.ExecuteNonQuery();
The end results of building this query should look something like this:
"begin;" +
" insert into profile(Username,TextInfo) values(#username,#textinfo);" +
" set #userid = LAST_INSERT_ID(); " +
" insert into achievement(Rank,Event,UserId) values (#rank0,#event0,#userid) (#rank1,#event1,#userid)" etc. etc. etc. +
" insert into social(URL,UserId) values(#url,#userid);" +
" COMMIT;"

Ive seen the problem
Your code:
string sql = "insert into achievement(Rank,Event,UserId) values ";
string valueSQL = "";
using (command = new MySqlCommand("begin;" +
" insert into profile(Username,TextInfo) values(#username,#textinfo);" +
" set #userid = LAST_INSERT_ID(); " +
sql +
" insert into social(URL,UserId) values(#url,#userid);" +
" COMMIT;", conn)
So. look carefully, at the sql string.. you didnt add the values to insert.. the syntax error would have pointed this out. I havent tried adding multiple rows in one insert like that, but, if that is valid, form the sql as you have but only after working out the sql variale.. eg more like
string sql = "insert into achievement(Rank,Event,UserId) values ";
string valueSQL = "";
for(int i = 0; i < dto.achievementDTOs.Count; i++)
{
valueSQL += /*(valueSQL == "" ? "": ",") +*/ "(#rank" + i + ",#event" + i + ",#userid)";
command.Parameters.AddWithValue("rank"+i, dto.achievementDTOs[i].Rank);
command.Parameters.AddWithValue("event"+i, dto.achievementDTOs[i].Event);
}
sql += valueSQL;
sql += ";";
using (command = new MySqlCommand("begin;" +
" insert into profile(Username,TextInfo) values(#username,#textinfo);" +
" set #userid = LAST_INSERT_ID(); " +
sql
" insert into social(URL,UserId) values(#url,#userid);" +
" COMMIT;", conn)

Related

Same SQL Query Working in Management Studio but Not Working From Visual Studio [duplicate]

This question already has answers here:
Incorrect syntax near 'GO'
(9 answers)
Closed 2 years ago.
I have a SQL query which creates a database and declares the path of an mdf and its log files. The same query works when I execute it in management studio (I am sure it's the same query I copy paste it from SQL Profiler) but gives a syntax error below:
incorrect syntax near go.
I have tried using executeNonQuery, ExecuteReader and ExecuteScalar to execute my query but nothing worked. It was giving syntax error due to the lack of newlines in query from my code hence the newline methods in the query. Any help would be appreciated.
Visual Studio code:
string truvamdf = #"C:\Truva\Data\"+VeritabaniAdiTextBox.Text+".mdf";
string truvaldf = #"C:\Truva\Data\"+VeritabaniAdiTextBox.Text+"_log.ldf";
string connectionString = (#"" + File.ReadAllText(#"C:\Truva\Ivdexcel\IVDVeritabaniconfig.ini") + "");
string cmdtext = "" +
"USE[master] " + Environment.NewLine + "" +
"GO " + Environment.NewLine + "" +
"DECLARE #mdfPath NVARCHAR(max), #ldfPath NVARCHAR(max) , #SQL NVARCHAR(MAX), #instName NVARCHAR(max) = '" + VeritabaniAdiTextBox.Text + "' " + Environment.NewLine + "" +
"SELECT #mdfPath = '" + truvamdf + "' " + Environment.NewLine + " " +
",#ldfPath = '" + truvaldf + "' " + Environment.NewLine + " " +
"FROM master.sys.master_files WHERE database_id = 1 " + Environment.NewLine + "" +
"SELECT #SQL = " + Environment.NewLine + "" +
"'CREATE DATABASE ["+VeritabaniAdiTextBox.Text+ "] " + Environment.NewLine + " " +
"CONTAINMENT = NONE " + Environment.NewLine + " " +
"ON PRIMARY " + Environment.NewLine + "" +
"(NAME = N'''+#instName+''', FILENAME = N'''+#mdfPath+''' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ) " + Environment.NewLine + " " +
" LOG ON " + Environment.NewLine + " " +
" (NAME = N'''+#instName+'_log'', FILENAME = N'''+#ldfPath+''' , SIZE = 2048KB , MAXSIZE = 2048GB , FILEGROWTH = 10 %)' "+Environment.NewLine+ " " + Environment.NewLine + "" +
"EXECUTE(#SQL) " + Environment.NewLine + " " + Environment.NewLine + "" +
" GO ";
// try
// {
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand cmd = new SqlCommand(cmdtext, connection);
cmd.ExecuteNonQuery();
}
The same SQL query in SSMS:
USE[master]
GO
DECLARE #mdfPath NVARCHAR(max), #ldfPath NVARCHAR(max) , #SQL NVARCHAR(MAX), #instName NVARCHAR(max) = 'dddssd'
SELECT #mdfPath = 'C:\Truva\Data\dddssd.mdf'
,#ldfPath = 'C:\Truva\Data\dddssd_log.ldf'
FROM master.sys.master_files WHERE database_id = 1
SELECT #SQL =
'CREATE DATABASE [dddssd]
CONTAINMENT = NONE
ON PRIMARY
(NAME = N'''+#instName+''', FILENAME = N'''+#mdfPath+''' , SIZE = 5120KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
(NAME = N'''+#instName+'_log'', FILENAME = N'''+#ldfPath+''' , SIZE = 2048KB , MAXSIZE = 2048GB , FILEGROWTH = 10 %)'
EXECUTE(#SQL)
GO
I just deleted the GO statements from the query and it works now!!

Insert and update a datetime into SQL database

private void ButtonOk_Click(object sender, EventArgs e)
{
if (txtWedstrijdSchemaID.Text == "")
{
//Insert
string SQL;
SQL = "Insert into Wedstrijdschema (Team1, Team2, Datum)";
SQL += " values (";
SQL += "" + txtTeam1.Text + ",";
SQL += "" + txtTeam2.Text + ",";
SQL += "" + Convert.ToDateTime(txtDatum.Text) + "";
SQL += ")";
clDatabase.ExecuteCommand(SQL);
vulLv();
}
else
{
//Update
string SQL;
SQL = "Update Wedstrijdschema SET ";
SQL += "Team1 = " + txtTeam1.Text + ",";
SQL += "Team2 = " + txtTeam2.Text + ",";
SQL += "Datum = " + Convert.ToDateTime(txtDatum.Text) + "";
SQL += " where SchemaId = " + zoek;
clDatabase.ExecuteCommand(SQL);
vulLv();
}
txtDatum.Enabled = txtTeam2.Enabled = txtTeam1.Enabled = false;
}
That is what I currently have, because of a trycatch it won't crash when I try, if I comment the txtDatum.Text out on the //insert and //upload it works (but obviously enters NULL for Datum in the Database) does anyone perhaps see where I'm going wrong?
EDIT: About the use of parameters, we need to use a threetier system where all SQL goes through a class which is the only one allowed to do anything with the database, this is how the command is executed:
public static bool ExecuteCommand(string SQLInstructie)
{
bool retour = true;
SqlConnection Conn = new SqlConnection(clStam.Connstr);
SqlCommand Cmd = new SqlCommand(SQLInstructie, Conn);
try
{
Cmd.Connection.Open();
Cmd.ExecuteNonQuery();
}
catch
{
retour = false;
}
finally
{
Conn.Close();
}
return retour;
}
This works!! Thanks a lot for the help:
private void ButtonOk_Click(object sender, EventArgs e)
{
if (txtWedstrijdSchemaID.Text == "")
{
//Insert
string SQL;
SQL = "Insert into Wedstrijdschema (Team1, Team2, Datum)";
SQL += " values (";
SQL += "" + txtTeam1.Text + ",";
SQL += "" + txtTeam2.Text + ",";
SQL += "'" + Convert.ToDateTime(txtDatum.Text) + "'";
SQL += ")";
Debug.WriteLine(SQL);
clDatabase.ExecuteCommand(SQL);
vulLv();
}
else
{
//Update
string SQL;
SQL = "Update Wedstrijdschema SET ";
SQL += "Team1 = " + txtTeam1.Text + ",";
SQL += "Team2 = " + txtTeam2.Text + ",";
SQL += "Datum = '" + Convert.ToDateTime(txtDatum.Text) + "'";
SQL += " where SchemaId = " + zoek;
clDatabase.ExecuteCommand(SQL);
vulLv();
}
txtDatum.Enabled = txtTeam2.Enabled = txtTeam1.Enabled = false;
}
EDIT: I'll promise to use parameterized SQL from now on!
You are missing a command , from the INSERT and UPDATE statement.
The syntax to insert data into the database is:
INSERT INTO Table
(Column1, Column2, Column3)
VALUES
('Value 1', 'Value 2', 'Value3')
Aside that, you are vulnerable to SQL injection, use SQL paramerterised queries to prevent this.
I would first start off by using a SqlCommand object.
SqlCommand cmd = new SqlCommand("INSERT INTO Wedstrijdschema (Team1, Team2, Datum) VALUES (#V1, #V2, #V3");
cmd.Parameters.AddWithValue("#V1", txtTeam1.Text);
cmd.Parameters.AddWithValue("#V2", txtTeam2.Text);
cmd.Parameters.AddWithValue("#V3", Convert.ToDateTime(txtDatum.Text));
And then execute it using cmd.ExecuteNonQuery();
As an additional note I would also ensure that the value in txtDatum is converted correctly to the desired date format.
remove single quotes from datetime column. also you missed column to add in insert statement
private void ButtonOk_Click(object sender, EventArgs e)
{
if (txtWedstrijdSchemaID.Text == "")
{
//Insert
string SQL;
SQL = "Insert into Wedstrijdschema (Team1, Team2,**Datum**)";
SQL += " values (";
SQL += "" + txtTeam1.Text + ",";
SQL += "" + txtTeam2.Text + "";
SQL += "" + Convert.ToDateTime(txtDatum.Text) + "";
SQL += ")";
clDatabase.ExecuteCommand(SQL);
vulLv();
}
else
{
//Update
string SQL;
SQL = "Update Wedstrijdschema SET ";
SQL += "Team1 = " + txtTeam1.Text + ",";
SQL += "Team2 = " + txtTeam2.Text + "";
SQL += "Datum = " + Convert.ToDateTime(txtDatum.Text) + "";
SQL += " where SchemaId = " + zoek;
clDatabase.ExecuteCommand(SQL);
vulLv();
}
txtDatum.Enabled = txtTeam2.Enabled = txtTeam1.Enabled = false;
}
Always use parameterized queries.string concatenations make a way to sql injection
private void ButtonOk_Click(object sender, EventArgs e)
{
if (txtWedstrijdSchemaID.Text == "")
{
SqlCommand cmd = new SqlCommand("Insert into Wedstrijdschema (Team1, Team2, Datum) values (#Team1,#Team2,#datetime)");
cmd.Parameters.AddWithValue("#Team1",txtTeam1.Text
cmd.Parameters.AddWithValue("#Team2",txtTeam2.Text
cmd.Parameters.AddWithValue("#datetime",Convert.ToDateTime(txtDatum.Text)
clDatabase.ExecuteCommand(SQL);
vulLv();
}
else
{
SqlCommand cmd = new SqlCommand("Update Wedstrijdschema SET Team1=#team1,Team2=#team2,Datum =#Datum where SchemaId=#SchemaId");
cmd.Parameters.AddWithValue("#team1",txtTeam1.Text );
cmd.Parameters.AddWithValue("#team2",txtTeam2.Text);
cmd.Parameters.AddWithValue("#Datum ",Convert.ToDateTime(txtDatum.Text);
cmd.Parameters.AddWithValue("#SchemaId",zoek);
clDatabase.ExecuteCommand(SQL);
vulLv();
}
txtDatum.Enabled = txtTeam2.Enabled = txtTeam1.Enabled = false;
}
Use ToString to format your date in an acceptable format (and enclose in quotes as it's being passed as a string):
string SQL;
SQL = "Insert into Wedstrijdschema (Team1, Team2, Datum)";
SQL += " values (";
SQL += "" + txtTeam1.Text + ",";
SQL += "" + txtTeam2.Text + ",";
SQL += "'" + Convert.ToDateTime(txtDatum.Text).ToString("yyyy-MM-dd HH:mm:ss") + "'";
SQL += ")";

Can I use SQLCLR stored procedure to update a column of a database table ( using some compiled dll)

I wanted to update the values of a few columns of a database table, using queries or stored procedure, but wanted to use my C# library to alter the value.
For eg, I want the columns A,B,C of table T to be replaced with Encrypt(A), Encrypt(B) and Encrypt(C) where Encrypt is a part of a C# library. I could have done it in a simple console application, but I have to do this process for a lot of columns in lot of tables.
Could I use a SQLCLR stored procedure / query to do this process in SQL Server Management Studio? It will be really great if someone could assist in this.
public class SP
{
[Microsoft.SqlServer.Server.SqlFunction()]
public static void Enc()
{
using (SqlConnection connection = new SqlConnection("context connection=true"))
{
connection.Open();
SqlCommand command;
SqlCommand command1;
for (int i = 0; i < 1; i++)
{
command = new SqlCommand("SELECT " + tableFieldArray[i, 1].ToString() + " FROM " + tableFieldArray[i, 0].ToString(), connection);
SqlDataReader reader = command.ExecuteReader();
using (reader)
{
while (reader.Read())
{
if (!reader.IsDBNull(0) && !String.IsNullOrEmpty(reader.GetString(0)))
{
//SqlContext.Pipe.Send("Data = " + reader.GetString(0) + "; Encrypted = " + Encrypt(reader.GetString(0)));
SqlContext.Pipe.Send("UPDATE " + tableFieldArray[i, 0].ToString() + " SET "
+ tableFieldArray[i, 1].ToString() + " = '" + Encrypt(reader.GetString(0)) + "' "
+ "WHERE " + tableFieldArray[i, 1].ToString() + " = '" + reader.GetString(0) + "'");
//query = "UPDATE " + tableFieldArray[i, 0].ToString() + " SET "
// + tableFieldArray[i, 1].ToString() + " = '" + Encrypt(reader.GetString(0)) + "' "
// + "WHERE " + tableFieldArray[i, 1].ToString() + " = '" + reader.GetString(0) + "'";
command1 = new SqlCommand("UPDATE " + tableFieldArray[i, 0].ToString() + " SET "
+ tableFieldArray[i, 1].ToString() + " = '" + Encrypt(reader.GetString(0)) + "' "
+ "WHERE " + tableFieldArray[i, 1].ToString() + " = '" + reader.GetString(0) + "'",connection);
}
}
}
SqlCommand command1 = new SqlCommand(query , connection);
command1.ExecuteNonQuery();
}
connection.Close();
}
}
public static string Encrypt(string TextFromForm)
{
//implementation
}
}
}
You can use SQLCLR to call encryption from C#, though this is the wrong approach. If you need to do a custom algorithm, you should encapsulate that into a SQLCLR function so that it can be used in an UPDATE statement or even an INSERT or SELECT or anywhere. Something like:
public class SP
{
[Microsoft.SqlServer.Server.SqlFunction(IsDeterministic = true)]
public static SqlString EncryptByAES(SqlString TextToEncrypt)
{
return DoSomething(TextToEncrypt.Value);
}
}
Then you can use that function as follows:
UPDATE tb
SET tb.FieldA = EncryptByAES(tb.FieldA)
FROM dbo.TableName tb
WHERE tb.FieldA some_test_to_determine_that_FieldA_is_not_alreay_encrypted;
BUT, before you write a custom encryption algorithm, you might want to check out the several built-in paired ENCRYPTBY / DECRYPTBY functions that might do exactly what you need:
ENCRYPTBYASYMKEY / DECRYPTBYASYMKEY
ENCRYPTBYCERT / DECRYPTBYCERT
ENCRYPTBYKEY / DECRYPTBYKEY
ENCRYPTBYPASSPHRASE / DECRYPTBYPASSPHRASE

SqlDataAdapter does not fill up datatable but SQL statement works fine in SQL Server Management Studio

I have trouble understanding why this doesn't work as it works for some of my SQL statements.
I am trying to populate a dataset using a SqlDataAdpter to store the select result and then use it to populate my result page
string sqlStr = "SELECT IRSwapId, " +
"i.InventoryName ," +
"Notional ," +
"TradeDate," +
"effectiveDate," +
"MaturityDate," +
"settleDate," +
"FixedRate," +
"ltrim(rtrim(cp.CounterParty))," +
"MurexReference," +
"case when PayReceiveFlag = -1 then 'Pay' else 'Receive' " +
"end as PayReceiveFlag," +
"ltrim(rtrim(c.currency)) ," +
"fixedValue," +
"floatValue," +
"comments," +
"CASE MurexUploadFlag WHEN 0 THEN 'N' WHEN 1 THEN 'Y' END " +
"FROM IRSwaps irs, Currency c, CounterParty cp, Inventory i " +
"WHERE i.InventoryID = irs.InventoryID AND cp.CounterPartyId = irs.CounterPartyId AND c.CurrencyID = irs.Currency " +
"AND IRSTypeId = '2' " +
(criteria == "" ? "" : " AND " + criteria + " ");
return Strucfin.Instance.Query(sqlStr).Tables[0].Rows;
public DataSet Query(string sqlStr)
{
DataSet ds = new DataSet();
lock (m_sfConn)
{
m_sqlDa = new SqlDataAdapter(sqlStr, m_sfConn);
m_sqlDa.Fill(ds);
}
return ds;
}
But when I enter ds.Tables[0].Rows in the immediate table, it shows me nothing, the sqlStr that I took from the local windows works in SQL Server Management Studio.
Thank you so much.

Insert or Update in one statement for access db

I am trying to wirte an sql statement such that I can either update (if record already exists) or insert a data record into an access db via an OleDBCommand.
sql statement:
string sql = "IF EXISTS (SELECT * FROM tblMitarbeiter_Arbeitsform WHERE (fkLogin = '" + _Login.ToUpper() + "') AND (fkIdArbeitsform = " + dr.fkIdArbeitsform + "))";
sql += " UPDATE tblMitarbeiter_Arbeitsform SET (Prozent = " + dr.Prozent + ")";
sql += " WHERE (fkLogin = '" + _Login.ToUpper() + "') AND (fkIdArbeitsform = " + dr.fkIdArbeitsform + ")";
sql += " ELSE INSERT INTO tblMitarbeiter_Arbeitsform (fkLogin, fkIdArbeitsform, Prozent) VALUES ('" + _Login.ToUpper() + "', " + dr.fkIdArbeitsform + ", " + dr.Prozent + ")";
oCmd = new OleDbCommand(sql, getOekobonusConnection());
oCmd.ExecuteScalar();
//oCmd.ExecuteNonQuery();
both ExecuteScalar and ExecuteNonQuery are not working. What am I doing wrong?
There's no control of flow constructs in Access SQL so you can't do an IF. You would have to split the logic and do the test in your code, then issue an update or insert accordingly.

Categories