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.
Related
As of right now I have a working piece of code, that looks something like this:
string sqlCreateDBQuery = " CREATE DATABASE "
+ "["+databaseName+"]"
+ " ON PRIMARY "
+ " (NAME = Data, "
+ " FILENAME = '" + strDataPath + databaseName + ".mdf', "
+ " FILEGROWTH = 1MB) "
+ " LOG ON (NAME = Log, "
+ " FILENAME = '" + strLogPath + databaseName + "_log.ldf', "
+ " FILEGROWTH = 10%) "
+ " COLLATE Latin1_General_CI_AS ;";
SqlCommand command = new SqlCommand(sqlCreateDBQuery, connection);
This has, with my current understanding, the potential issue of SQL-Injection attacks and well, user input errors.
So my question is, how do I safely create a database programmatically on an SQL Server where the user is able to name the database?
I know that one should use parameterized SQL-Queries to avoid SQL-Injection attempts, but for some reason I can´t seem to figure out how to do this for creating a new database or users/logins.
I´ve also read, that there is the option to use the SQL Server Management Object API as described in this answer here: Creating a database programmatically in SQL Server
Unfortunately this is not an option for us.
As of right now I haven´t figured out how to use a parameterized Query for this task.
This is what I would assume what the Code should look like to achieve this, but with no working result.
SqlCommand command = connection.CreateCommand();
command.CommandText = " CREATE DATABASE "
+ "#dbName"
+ " ON PRIMARY "
+ " (NAME = Data, "
+ " FILENAME = #dataPath, "
+ " FILEGROWTH = 1MB) "
+ " LOG ON (NAME = Log, "
+ " FILENAME = #logPath, "
+ " FILEGROWTH = 10%) "
+ " COLLATE Latin1_General_CI_AS ;";
command.Parameters.AddWithValue("#dbName", StrDBName);
command.Parameters.AddWithValue("#dataPath", $"{strDataPath}{StrDBName}.mdf");
command.Parameters.AddWithValue("#logPath", $"{strLogPath}{StrDBName}_log.ldf");
I´ve also read Here that this should be possible with dynamic SQL, but sadly all my attempts either ended in Syntax errors or the parameters not being replaced by the actual values.
Am I missing something here or is this just not as trivial as I initially thought?
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)
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
I want to insert multiple pieces of data into a SQL Server database as shown below, but when I run this code, I get a syntax error
Incorrect syntax near the keyword 'union'.
Incorrect syntax near ''.
Incorrect syntax near ''.
Incorrect syntax near ''.
Code:
SqlCommand cmd2 = new SqlCommand("INSERT INTO [rampDB].[dbo].[Answers]([AssessmentID],[questionID],[result],[comment]) SELECT('"
+ assessmentid + "1.1a" + RadioButtonList1.SelectedItem.Value.ToString() + TextBox1.Text + "'union'"
+ "'SELECT'" + assessmentid + "1.1b" + RadioButtonList2.SelectedItem.Value.ToString() + TextBox2.Text + "'union'"
+ "'SELECT'" + assessmentid + "1.1c" + RadioButtonList3.SelectedItem.Value.ToString() + TextBox3.Text + "'union'"
+ "'SELECT'" + assessmentid + "1.1d" + RadioButtonList4.SelectedItem.Value.ToString() + TextBox4.Text + "'union'"
+ "'SELECT'" + assessmentid + "1.1e" + RadioButtonList5.SelectedItem.Value.ToString() + TextBox5.Text
+ "')", sqlConn);
Multiple-insert syntax for SQL Server is possible with only INSERT, like so:
INSERT INTO rampDB.dbo.Answers (
assessmentID, QuestionId, Result, Comment
) VALUES
( #r1v1, #r1v2, #r1v3, #r1v4 ),
( #r2v1, #r2v2, #r2v3, #r2v4 ),
( #r3v1, #r3v2, #r3v3, #r3v4 )
That said, the best way is to use a single INSERT with parameters, which is then executed for each row.
Relpace "'union'" with this--> "union"
I am new to programming and is developing a new desktop database applcation in Access, I am trying to insert data into a table. I had two datetime picker and I read the value from it as
jobcodedatabean.PaperRecievedate1 = dtpjobcodedate.Value.Date;
jobcodedatabean.Shipmenentdate = dtpshipmentdate.Value.Date;
and I had passed the databean to a function
public void addaction(JobCodeDataBean jobcodedatabean)
{
MessageBox.Show(jobcodedatabean.Shipmenentdate.ToString());
try
{
OleDbConnection oleDbConnection1 = new System.Data.OleDb.OleDbConnection(connString);
oleDbConnection1.Open();
OleDbCommand oleDbCommand1 = new System.Data.OleDb.OleDbCommand("INSERT INTO jobcodemastertable (jobcode ,customercode,totaltrip,shipmentdate,fromPlace, destination,description ,packagetype ,noofpackage ,contactperson ,jobecodedate ) Values ('" + jobcodedatabean.Jobcode + "', '" + jobcodedatabean.Customercode + "' ," + jobcodedatabean.Totaltrip + "," + jobcodedatabean.Shipmenentdate + " ,'" + jobcodedatabean.Fromplace + "','" + jobcodedatabean.Destination + "','" + jobcodedatabean.Description + "','" + jobcodedatabean.Typeofpackage + "','" + jobcodedatabean.Noofpackages + "','" + jobcodedatabean.Contactperson + "'," + jobcodedatabean.PaperRecievedate1 + ") ", oleDbConnection1);
oleDbCommand1.CommandType = CommandType.Text;
oleDbCommand1.ExecuteNonQuery();
oleDbConnection1.Close();
}
catch (Exception)
{
MessageBox.Show(e);
}
but i am getting the exception at the query
Syntax error (missing operator) in query expression '2/16/2012 12:00:00 AM'.
In access the date fields are in short date format
Please somebody help to sort out my mistake
Incorrect quotations. To avoid these kinds of mistakes, use ordered parameters:
var myCommand = new OleDbCommand(
"INSERT INTO MyTable(someDateField, someTextField, someNumberField) VALUES (?, ?, ?)"
);
myCommand.Parameters.Add(DateTime.Now);
myCommand.Parameters.Add("Some text");
myCommand.Parameters.Add(123);
Using parameters also helps protect against SQL injection attacks. In your example, if one of the strings contained an apostrophe, it would fail unless you correctly converted it to two apostrophes. With parameters these are escaped correctly automatically.
You forgot to enclose dates in quotes:
... ",'" + jobcodedatabean.Shipmenentdate + "' ,'" ...
... "','" + jobcodedatabean.PaperRecievedate1 + "') " ...
Note single quotes around both dates.