I created this function that inserts new records -- I submit query directly to it.
My question- is it optimal? It is it fool proof and guaranteed to function normally? If not; please advise.
static String Server = "";
static String Username = "";
static String Name = "";
static String password = "";
static String conString = "SERVER=" + Server + ";DATABASE=" + Name + ";UID=" + Username + ";PASSWORD=" + password + ";connect timeout=500000;Compress=true;";
public bool InsertSQL(String Query)
{
int tmp = 0;
try
{
using (MySqlConnection mycon = new MySqlConnection(conString))
{
using (MySqlCommand cmd = new MySqlCommand(Query, mycon))
{
mycon.Open();
try
{
tmp = cmd.ExecuteNonQuery();
}
catch
{
if (mycon.State == ConnectionState.Open)
{
mycon.Close();
}
}
mycon.Close();
}
}
}
catch { return tmp > 0 == true ? true : false; }
return tmp > 0 == true ? true : false;
}
This is my SQL insert that I create in other function and pass as text to insert function. I am open to all suggestions!
String insertSql = #"INSERT INTO `gps_unit_location`
(`idgps_unit`,`lat`,`long`,`ip`,`unique_id`,
`loc_age`,`reason_code`,`speed_kmh`,
`VehHdg`,`Odometer`,`event_time_gmt_unix`,`switches`, `engine_on_off`, `dt`)
VALUES
(
(Select idgps_unit from gps_unit where serial=" + serial + "),'" + lat + "','" + lon + "','" + IP + "','" + unique_id + #"',
'" + LocAge_mins + "','" + ReasonCode + "','" + Speed + #"',
'" + VehHdg + "','" + Odometer + "','" + EventTime_GMTUnix + "','" + Switches + "', '" + engine_on_off + #"', DATE_ADD(NOW(), INTERVAL 1 HOUR))
";
I built this answer using your code as the example. Take note of the following line:
cmd.Parameters.AddWithValue("#queryParam", Query);
It is always a best-practice to code for potential SQL Injection attacks even if they are unlikely to happen.
static String Server = "";
static String Username = "";
static String Name = "";
static String password = "";
static String conString = "SERVER=" + Server + ";DATABASE=" + Name + ";UID=" + Username + ";PASSWORD=" + password + ";connect timeout=500000;Compress=true;";
public bool InsertSQL(String Query)
{
int tmp = 0;
try
{
using (MySqlConnection mycon = new MySqlConnection(conString))
{
using (MySqlCommand cmd = new MySqlCommand(Query, mycon))
{
mycon.Open();
try
{
cmd.Parameters.AddWithValue("#queryParam", Query);
tmp = cmd.ExecuteNonQuery();
}
catch
{
if (mycon.State == ConnectionState.Open)
{
mycon.Close();
}
}
mycon.Close();
}
}
}
catch { return tmp > 0 == true ? true : false; }
return tmp > 0 == true ? true : false;
}
By making this so generic, you are leaving yourself open to SQL injection. I am guessing you have to build the query and insert values directly. SQL parameters would be better here, you could potentially pass in a params of SqlParameters, however that would still rely on generic text being sent and still leaves you open to an injection.
Here is a SQL Parameter example
Related
I need to execute my SQL Server xevent creation with my C# and starting it then read its content from file. The query executes fine and no errors are displayed however the session is not added in SQL Server so no results are returned. I executed the query on SSMS and it works with concatenation of the variables to the query with N' but when I copy the same to C# it shows incorrect syntax though. Any help?
My C#:
public ActionResult CreateSession(string id)
{
System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(connectionString);
string dbName = id;
string path = #".\\wwwroot\\ExecutedQueries\\"+dbName;
System.IO.Directory.CreateDirectory(path);
string fileName = dbName +DateTime.Now.ToString("dd_MM_yyyy_hh_mm_ss") +".xel";
string pathString = System.IO.Path.Combine(path, fileName);
if (!System.IO.File.Exists(pathString))
{
System.IO.FileStream fs = System.IO.File.Create(pathString);
}
string sql="DECLARE #sql nvarchar(max) = N'CREATE EVENT SESSION " + dbName + "_Session1"
+ " ON SERVER" + "ADD EVENT sqlserver.sql_statement_completed"
+ "(ACTION(sqlserver.sql_text, sqlserver.tsql_stack, sqlserver.client_app_name," +
" sqlserver.client_hostname, sqlserver.username) WHERE(sqlserver.database_name =''" + dbName + "'')),"
+ "ADD EVENT sqlserver.sql_statement_starting(ACTION(sqlserver.sql_text, sqlserver.tsql_stack, sqlserver.client_app_name, sqlserver.client_hostname, sqlserver.username) WHERE(sqlserver.database_name =''" + dbName + "''))"
+ "ADD target package0.event_file( SET filename =''" + pathString + "'')"
+ "WITH(MAX_MEMORY = 4096 KB, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,"
+ "MAX_DISPATCH_LATENCY = 30 SECONDS, MAX_EVENT_SIZE = 0 KB,"
+ " MEMORY_PARTITION_MODE = NONE, TRACK_CAUSALITY = OFF, STARTUP_STATE = OFF);";
using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(sql, con))
{
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
return RedirectToAction("BeginSession", new { database = dbName });
}
public ActionResult BeginSession(string database)
{
System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(connectionString);
string sql = "DECLARE #sql nvarchar(max) = N'ALTER EVENT SESSION "+#database+"_Session1 ON SERVER STATE = START '";
using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(sql, con))
{
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
return RedirectToAction("ExecutedQueries", new { dataBase = database });
}
public ActionResult ExecutedQueries(string dataBase)
{
System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(connectionString);
string path = #"./wwwroot/ExecutedQueries/" + dataBase
string fileName = dataBase + "*.xel";
string pathString = System.IO.Path.Combine(path, fileName);
try
{
byte[] readBuffer = System.IO.File.ReadAllBytes(pathString);
foreach (byte b in readBuffer)
{
Console.Write(b + " ");
}
Console.WriteLine();
}
catch (System.IO.IOException e)
{
Console.WriteLine(e.Message);
}
return View();
}
This generates SQL that can be executed:
string sql = "CREATE EVENT SESSION " + dbName + "_Session1" +
" ON SERVER" +
" ADD EVENT sqlserver.sql_statement_completed" +
"( ACTION(sqlserver.sql_text, sqlserver.tsql_stack, sqlserver.client_app_name," +
" sqlserver.client_hostname, sqlserver.username) WHERE(sqlserver.database_name ='" + dbName + "'))," +
"ADD EVENT sqlserver.sql_statement_starting( ACTION(sqlserver.sql_text, sqlserver.tsql_stack, sqlserver.client_app_name,sqlserver.client_hostname, sqlserver.username) WHERE(sqlserver.database_name ='" + dbName + "'))" +
"ADD target package0.event_file( SET filename ='" + pathString + "')" +
"WITH(MAX_MEMORY = 4096 KB, EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS," +
"MAX_DISPATCH_LATENCY = 30 SECONDS, MAX_EVENT_SIZE = 0 KB," +
" MEMORY_PARTITION_MODE = NONE, TRACK_CAUSALITY = OFF, STARTUP_STATE = OFF);";
I've changed it so that it's creating the event directly (instead of creating a #sql variable which wasn't executed), and there was a missing space before ADD EVENT, which was generating SERVERADD instead of SERVER ADD.
I've a problem with SqlConnection in C#. I do a large number of INSERT NonQuery, but in any case SqlConnection save in the database always the first 573 rows. This is the method I use for queries. In this method there is a lock because I use different thread to save the data.
public void InsertElement(string link, string titolo, string text)
{
string conString = "*****************";
using (SqlConnection connection = new SqlConnection(conString))
{
connection.Open();
text = text.Replace("\"", "");
DateTime localDate = DateTime.Now;
lock (thisLock)
{
string query = "IF (NOT EXISTS(SELECT * FROM Result " +
" WHERE Link = '" + link + "')) " +
" BEGIN " +
" INSERT INTO Result ([Titolo],[Link],[Descrizione],[DataRicerca],[FKDatiRicercheID]) " +
" VALUES('" + titolo + "', '" + link + "', '" + text + "', '" + localDate + "', 1) " +
" END";
if (connection != null)
{
SqlCommand cmd = new SqlCommand(query, connection);
cmd.ExecuteNonQuery();
}
}
}
}
This is the code of the loop that call the method InsertElement()
public void Save()
{
string[] DatiLetti;
string url = "";
while (result.Count > 0)
{
try
{
url = result.Last();
result.RemoveAt(result.Count - 1);
DatiLetti = ex.DirectExtractText(url);
if (DatiLetti[0].Length > 2)
{
ssc.InsertGare(url, DatiLetti[0], DatiLetti[1]);
}
}
catch (Exception exc)
{
logger.Error("Exception SpiderSave> " + exc);
}
}
}
Result is a volatile array that is progressively filled from other thread. I'm sure that the array contains more than 573 items.
I try to search one solution, but all the answers say that the number of database connections for SQLServer is over 32K at a time and I've already checked this number in my database. Is there anyone who can help me understand the problem?
Don't open a connection for every insert. Use one connection, then pass that connection through to your insert, like this :
public void InsertElement(string link, string titolo, string text, SqlConnection conn)
{
text = text.Replace("\"", "");
DateTime localDate = DateTime.Now;
lock (thisLock)
{
string query = "IF (NOT EXISTS(SELECT * FROM Result " +
" WHERE Link = '" + link + "')) " +
" BEGIN " +
" INSERT INTO Result ([Titolo],[Link],[Descrizione],[DataRicerca],[FKDatiRicercheID]) " +
" VALUES('" + titolo + "', '" + link + "', '" + text + "', '" + localDate + "', 1) " +
" END";
if (connection != null)
{
SqlCommand cmd = new SqlCommand(query, connection);
cmd.ExecuteNonQuery();
}
}
}
I recommend also looking at paramatizing your query, as well as using bulk inserts, and not individual inserts
If you are executing InsertElement() once for each rows of data to insert, then the execution will be too slow for large no. of rows. (Also, you are creating SqlConnection for each query execution.) Try adding many rows at once using a single INSERT query:
INSERT INTO tablename
(c1,c2,c3)
VALUES
(v1,v2,v3),
(v4,v5,v6)
...
i have this code that is being used to enter data into mysql, but I have found an error that says:
"MySql.Data.MySqlClient.MySqlException: 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''11/05/2018)' at line 1'"
private void Button_Click(object sender, RoutedEventArgs e)
{
string especie = txt1.Text;
string nombre = txt2.Text;
string fechanac = txt3.Text;
string fecharev = txt4.Text;
int numanimales = 0;
int cont = 0;
var dbCon = DBConnection.Instance();
dbCon.DatabaseName = "animalia";
if (dbCon.IsConnect())
{
string query = "SELECT COUNT(*) FROM ANIMALES;";
var cmd = new MySqlCommand(query, dbCon.Connection);
numanimales = Convert.ToInt32(cmd.ExecuteScalar());
}
int id = numanimales + 1;
if (dbCon.IsConnect())
{
if (especie == "" || nombre == "" || fechanac == "" || fecharev == "")
{
MessageBox.Show("Introduzca todos los datos");
}
else
{
cont = 1;
MySqlDataReader reader;
string query = "INSERT INTO ANIMALES VALUES (" + id + ",FALSE,'" + especie + "','" + nombre + "','" + fechanac + "','" + fecharev + "');";
var cmd = new MySqlCommand(query, dbCon.Connection);
reader = cmd.ExecuteReader();
MessageBox.Show("Animal añadido");
reader.Close();
}
if (cont == 1)
{
this.Close();
}
}
}
}
The error appears in this part of the code
MySqlDataReader reader;
string query = "INSERT INTO ANIMALES VALUES (" + id + ",FALSE,'" + especie + "','" + nombre + "','" + fechanac + "','" + fecharev + ");";
var cmd = new MySqlCommand(query, dbCon.Connection);
reader = cmd.ExecuteReader();
MessageBox.Show("Animal añadido");
reader.Close();
Thank you very much in advance to those of you who can help me.
You are missing closing quotation marks on the last attribute:
...,'" + fecharev + ");";
should be
...,'" + fecharev + "');";
protected void ImageButton2_Click(object sender, ImageClickEventArgs e)
{
string loginID = (String)Session["UserID"];
string ID = txtID.Text;
string password = txtPassword.Text;
string name = txtName.Text;
string position = txtPosition.Text;
int status = 1;
string createOn = validate.GetTimestamp(DateTime.Now); ;
string accessRight;
if (RadioButton1.Checked)
accessRight = "Administrator";
else
accessRight = "Non-administrator";
if (txtID.Text != "")
ClientScript.RegisterStartupScript(this.GetType(), "yourMessage", "alert('" + ID + "ha " + password + "ha " + status + "ha " + accessRight + "ha " + position + "ha " + name + "ha " + createOn + "');", true);
string sqlcommand = "INSERT INTO USERMASTER (USERID,USERPWD,USERNAME,USERPOISITION,USERACCESSRIGHTS,USERSTATUS,CREATEDATE,CREATEUSERID) VALUES ("+ ID + "," + password + "," + name + "," + position + "," + accessRight + "," + status + "," + createOn + "," +loginID+ ")";
readdata.updateData(sqlcommand);
}
I am passing the sqlcommand to readdata class for execute..and its throw me this error..
ORA-00917: missing comma
Description: An unhandled exception occurred during the execution of
the current web request. Please review the stack trace for more
information about the error and where it originated in the code.
Exception Details: System.Data.OleDb.OleDbException: ORA-00917:
missing comma.
The readdata class function code as below.
public void updateData(string SqlCommand)
{
string strConString = ConfigurationManager.ConnectionStrings["SOConnectionString"].ConnectionString;
OleDbConnection conn = new OleDbConnection(strConString);
OleDbCommand cmd = new OleDbCommand(SqlCommand, conn);
OleDbDataAdapter daPerson = new OleDbDataAdapter(cmd);
conn.Open();
cmd.ExecuteNonQuery();
}
Given that most of your columns are variable-length character, they must be enclosed in single quotes.
So, instead of:
string sqlcommand = "INSERT INTO myTable (ColumnName) VALUES (" + InputValue + ")";
You would, at minimum, need this:
string sqlcommand = "INSERT INTO myTable (ColumnName) VALUES ('" + InputValue + "')";
The result of the first statement, for an InputValue of "foo", would be:
INSERT INTO myTable (ColumnName) VALUES (foo)
which would result in a syntax error.
The second statement would be formatted correctly, as:
INSERT INTO myTable (ColumnName) VALUES ('foo')
Additionally, this code seems to be using values entered directly by the user, into txtID, txtPassword, and so on. This is a SQL Injection attack vector. Your input needs to be escaped. Ideally, you should use parameterized queries here.
This appears to be c#. Please update your tags accordingly.
At any rate, if it is .Net, here is some more information about parameterizing your queries:
OleDbCommand.Parameters Property
OleDbParameter Class
Try this
string sqlcommand = "INSERT INTO USERMASTER (USERID,USERPWD,USERNAME,USERPOISITION,USERACCESSRIGHTS,USERSTATUS,CREATEDATE,CREATEUSERID) VALUES ('"+ ID + "','" + password + "','" + name + "','" + position + "','" + accessRight + "','" + status + "','" + createOn + "','" +loginID+ "')";
Concatenating the query and executing it is not reccomended as it may cause strong SQl Injection. Suppose if any one of those parameters contain a comma(,) like USERPWD=passwo',rd then query will devide it as passwo and rd by the comma. This may be a problem
It is recommended that you use "Parameterized queries to prevent SQL Injection Attacks in SQL Server" and hope it will resolve your issue.
Your code can be rewritten as follows
protected void ImageButton2_Click(object sender, ImageClickEventArgs e)
{
string loginID = (String)Session["UserID"];
string ID = txtID.Text;
string password = txtPassword.Text;
string name = txtName.Text;
string position = txtPosition.Text;
int status = 1;
string createOn = validate.GetTimestamp(DateTime.Now); ;
string accessRight;
if (RadioButton1.Checked)
accessRight = "Administrator";
else
accessRight = "Non-administrator";
if (txtID.Text != "")
ClientScript.RegisterStartupScript(this.GetType(), "yourMessage", "alert('" + ID + "ha " + password + "ha " + status + "ha " + accessRight + "ha " + position + "ha " + name + "ha " + createOn + "');", true);
string strQuery;
OleDbCommand cmd;
strQuery = "INSERT INTO USERMASTER(USERID,USERPWD,USERNAME,USERPOISITION,USERACCESSRIGHTS,USERSTATUS,CREATEDATE,CREATEUSERID) VALUES(#ID,#password,#name,#position,#accessRight,#status,#createOn,#loginID)";
cmd = new OleDbCommand(strQuery);
cmd.Parameters.AddWithValue("#ID", ID);
cmd.Parameters.AddWithValue("#password", password);
cmd.Parameters.AddWithValue("#name", name);
cmd.Parameters.AddWithValue("#position", position);
cmd.Parameters.AddWithValue("#accessRight", accessRight);
cmd.Parameters.AddWithValue("#status", status);
cmd.Parameters.AddWithValue("#createOn", createOn);
cmd.Parameters.AddWithValue("#loginID", loginID);
bool isInserted = readdata.updateData(cmd);
}
rewrite your updateData data as follows
private Boolean updateData(OleDbCommand cmd)
{
string strConString = ConfigurationManager.ConnectionStrings["SOConnectionString"].ConnectionString;
OleDbConnection conn = new OleDbConnection(strConString);
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
try
{
con.Open();
cmd.ExecuteNonQuery();
return true;
}
catch (Exception ex)
{
Response.Write(ex.Message);
return false;
}
finally
{
con.Close();
con.Dispose();
}
}
i was trying to update two tables at once, but i got some syntax error on update code could u give me some idea? the insert code works perfect and i tried to copy the insert code and edit on update button clicked
here is my code
private void button2_Click(object sender, EventArgs e)
{
System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection();
conn.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;" +
#"Data source= C:\Users\user\Documents\Visual Studio 2010\Projects\WindowsFormsApplication1\WindowsFormsApplication1\crt_db.accdb";
try
{
conn.Open();
String Name = txtName.Text.ToString();
String AR = txtAr.Text.ToString();
String Wereda = txtWereda.Text.ToString();
String Kebele = txtKebele.Text.ToString();
String House_No = txtHouse.Text.ToString();
String P_O_BOX = txtPobox.Text.ToString();
String Tel = txtTel.Text.ToString();
String Fax = txtFax.Text.ToString();
String Email = txtEmail.Text.ToString();
String Item = txtItem.Text.ToString();
String Dep = txtDep.Text.ToString();
String k = "not renwed";
String Remark = txtRemark.Text.ToString();
String Type = txtType.Text.ToString();
String Brand = txtBrand.Text.ToString();
String License_No = txtlicense.Text.ToString();
String Date_issued = txtDate.Text.ToString();
String my_querry = "update crtPro set Name='" + Name + "',AR='" + AR + "',Wereda='" + Wereda + "',Kebele='" + Kebele + "',House_No='" + House_No + "',P_O_BOX='" + P_O_BOX + "',Tel='" + Tel + "',Fax='" + Fax + "',Email='" + Email + "',Item='" + Item + "',Dep='" + Dep + "','" + k + "',Remark='" + Remark + "' where Name='" + Name + "' ";
OleDbCommand cmd = new OleDbCommand(my_querry, conn);
cmd.ExecuteNonQuery();
String my_querry1 = "SELECT max(PID) FROM crtPro";
OleDbCommand cmd1 = new OleDbCommand(my_querry1, conn);
string var = cmd1.ExecuteScalar().ToString();
String ki = txtStatus.Text.ToString();
String my_querry2 = "update crtItemLicense set PID=" + var + ",Type='" + Type + "',Brand='" + Brand + "',License_No='" + License_No + "',Date_issued='" + Date_issued + "' where PID=" + var + "";
OleDbCommand cmd2 = new OleDbCommand(my_querry2, conn);
cmd2.ExecuteNonQuery();
MessageBox.Show("Message added succesfully");
}
catch (Exception ex)
{
MessageBox.Show("Failed due to" + ex.Message);
}
finally
{
conn.Close();
}
The most likely problem based on the little information given (what database are you using for example - SQL Server 2012?), is that the datatype you are providing in the concatenated dynamic sql does not match the datatype of the column in the database. You've surrounded each value with quotes - which means it will be interpreted as a varchar. If you've got a date value in the wrong format (ie if Date_Issued is a date column) or if it is a number column, then it will error.
The solution is to replace your dynamic SQL with a parameterized query eg:
String my_querry = "update crtPro set Name=#name, AR=#ar, Wereda=#Wereda, etc ...";
OleDbCommand cmd = new OleDbCommand(my_querry, conn);
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#name", Name);
cmd.Parameters.AddWithValue("#myParam", Convert.ToDateTime(txtDate.Text.Trim()));
...
cmd.ExecuteNonQuery();
You can read about it further here
PS Make sure your parameters are in the same order as they are used in the SQL, because oledbcommand doesn't actually care what you call them. see here