I am writing a small app using WPF/C# & SQLITE.
One of the functions inserts a record containing two date/time values into a table.
I want to know if there is a proper way to do this (to ensure that the date/month fields are stored consistently).
I have created an INSERT query that uses parameters alongside date variables (clsVariables.DatActivityEnd = DateTime.Now;).
String cntnStr = ClsVariables.StrDb;
var connection = new SQLiteConnection(cntnStr);
connection.Open();
using (SQLiteCommand cmd = connection.CreateCommand())
{
cmd.CommandText =
"INSERT INTO tblActivity ([Activity_Category], [Activity_Category_Sub], [Activity_Start], [Activity_End], [Activity_Duration]) VALUES (#ActivityCategory, #ActivityCategorySub, #ActivityStart, #ActivityEnd, #ActivityDuration);";
cmd.Parameters.Add(new SQLiteParameter("#ActivityCategory", ClsVariables.StrActivityCurrent));
cmd.Parameters.Add(new SQLiteParameter("#ActivityCategorySub", ClsVariables.StrActivitySubCurrent));
cmd.Parameters.Add(new SQLiteParameter("#ActivityStart", ClsVariables.DatActivityStart.ToString()));
cmd.Parameters.Add(new SQLiteParameter("#ActivityEnd", ClsVariables.DatActivityEnd.ToString()));
cmd.Parameters.Add(new SQLiteParameter("#ActivityDuration", ClsVariables.DblActivityDuration));
cmd.ExecuteNonQuery();
}
connection.Close();
Is there anything else I should do - Thank you?
You have to use sql formatted strings:
string sqlFormattedDate = myDateTime.ToString("yyyy-MM-dd HH:mm:ss");
Update:
Today I would prefer AddWithValues with Type Safety and without any Conversion:
cmd.Parameters.AddWithValue("#ActivityStart", ClsVariables.DatActivityStart);
Related
Storing Japanese characters from a form TextBox to SQL table appears as question marks.
I'm just trying to make a table that holds the Japanese text and the English translation to make my life easier as I'm studying Japanese.
Searching for a solution 2 days now nothing seems to be working.
I am not even sure if this is actually a good practice for storing text to data table.
Also column where I want the Japanese character stored is set to nvarchar(50).
private void addWordButton_Click(object sender, EventArgs e)
{
con.Open();
System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = "INSERT Words (WordJapanese, WordEnglish) VALUES ('" + newJPwordTxt.Text + "', '" +
newENwordTxt.Text + "')";
cmd.Connection = con;
cmd.ExecuteNonQuery();
con.Close();
}
It seems you have missed the into keyword in your Insert statement, as a second note, you need to be aware that this kind of string concatenation is avoided and it is open to SQL Injection attack. You should always use parameterized queries to avoid SQL Injection:
cmd.CommandText = "INSERT into Words (WordJapanese, WordEnglish) VALUES (#WordJapanese, #WordEnglish)";
cmd.Parameters.Add("#WordJapanese", SqlDbType.NVarChar, 50).Value = newJPwordTxt.Text;
cmd.Parameters.Add("#WordEnglish", SqlDbType.NVarChar, 50).Value = newENwordTxt.Text;
Your query has syntax issues and secondly you should be using parameterized queries to safeguard from SQL Injection.
The following should be good :
cmd.CommandText = "INSERT INTO Words(WordJapanese, WordEnglish) VALUES (#Japanse, #English)";
cmd.Parameters.Add("#Japanse", SqlDbType.NVarChar, 50).Value = newJPwordTxt.Text;
cmd.Parameters.Add("#English", SqlDbType.NVarChar, 50).Value = newENwordTxt.Text;
New to C#. Trying to insert values into a Microsoft Access Database using this code:
string value = "It's a nice day"
con.Open();
OleDbCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "insert into Table1 values('"+ value + "')";
cmd.ExecuteNonQuery();
con.Close();
But I get the error 'Syntax error (missing operator) in query expression' which I'm going to assume, stems from the apostrophe in the string value. Is there any way around this?
Every time you need to pass values to execute an sql query you should ALWAYS use a parameterized query. As you have experienced, apostrophes mess with the syntax when you concatenate strings.
A parameterized query for your case should be
string value = "It's a nice day"
OleDbCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "insert into Table1 values(#value)";
cmd.Parameters.Add("#value", OleDbType.VarWChar).Value = value;
cmd.ExecuteNonQuery();
This will remove the problem with apostrophes, interpretation of the decimal point symbol, date format, but, most important even is not easy to exploit with Access, the Sql Injection ack.
I'm developing a front end for retro gaming. Upon boot I'm parsing a lot of xml files from another application so I end up with a List of "systems" each containing a list of "games". Parsing the xml data is really fast, but writing all this to the sqlite database is not. Currently it takes ~25 seconds (20.000 records) which may not be too bad, but hopefully I can get some ideas on how to make it even faster.
Ideally I want to be able to compare my object containing all the data with the sqlite database. If anything has changed in the xml files/parsed object the data should be updated or deleted from the database. Is there a better way of solving this then doing a initial import and then dump all of the database and compare it to the object? Basically the whole import code backwards...
This is my current code:
public static void PopulateDatabase(List<RetroBoxSystem> systems)
{
using (SQLiteConnection con = new SQLiteConnection("Data Source=RetroBox.db;Version=3;"))
{
con.Open();
using (SQLiteTransaction tr = con.BeginTransaction())
{
using (SQLiteCommand cmd = con.CreateCommand())
{
foreach (var system in systems)
{
cmd.CommandText = #"INSERT OR IGNORE INTO systems(system_id, name)
VALUES ((SELECT system_id FROM systems WHERE name = #name), #name)";
cmd.Parameters.Add(new SQLiteParameter("#name", system.Name));
cmd.ExecuteNonQuery();
}
}
using (SQLiteCommand cmd = con.CreateCommand())
{
cmd.CommandText = #"INSERT OR IGNORE INTO games(game_id, system_id, name, description, cloneof, manufacturer, genre, rating, year)
VALUES ((SELECT game_id FROM games WHERE name = #name), (SELECT system_id FROM systems WHERE name = #system), #name, #description, #cloneof, #manufacturer, #genre, #rating, #year)";
foreach (var system in systems)
{
foreach (var g in system.GameList)
{
cmd.Parameters.Add(new SQLiteParameter("#system", system.Name));
cmd.Parameters.Add(new SQLiteParameter("#name", g.Name));
cmd.Parameters.Add(new SQLiteParameter("#description", g.Description));
cmd.Parameters.Add(new SQLiteParameter("#cloneof", g.CloneOf));
cmd.Parameters.Add(new SQLiteParameter("#manufacturer", g.Manufacturer));
cmd.Parameters.Add(new SQLiteParameter("#genre", g.Genre));
cmd.Parameters.Add(new SQLiteParameter("#rating", g.Rating));
cmd.Parameters.Add(new SQLiteParameter("#year", g.Year));
cmd.ExecuteNonQuery();
}
}
}
tr.Commit();
}
}
}
Your best bet would be the Entity Framework for comparing objects without coding everything yourself, however depending on your project type you might not have access to it (such as Windows Phone projects).
Your insert query seems pretty optimized, but maybe you can make it faster using async inserts with ConfigureAwait(false).
More details about ConfigureAwait here: How to massively improve SQLite Performance (using SqlWinRT)
I have a birthdate column of type Date in sql database
And in my application I use a dateTimePicker to get the birth date
But when i am trying to insert the date taken from the dateTimePicker:
I get an error :
Incorrect syntax near '12'
And when I try to debug the code I find that the value taken from the dateTimePicker is
Date = {3/21/2015 12:00:00 AM}
The CODE:
//cmd is sql command
cmd.CommandText="INSERT INTO person (birthdate) VALUES("+dateTimePicker.Value.Date+")";
//con is sql connection
con.Open();
cmd.ExecuteNonQuery();
con.Close();
What you really should do is use parameters to avoid SQL injection attacks - and it also frees you from string formatting dates - also a good thing!
//cmd is sql command
cmd.CommandText = "INSERT INTO dbo.Person(birthdate) VALUES(#Birthdate);";
cmd.Parameters.Add("#Birthdate", SqlDbType.Date).Value = dateTimePicker.Value.Date;
//con is sql connection
con.Open();
cmd.ExecuteNonQuery();
con.Close();
Also, it's a recommend best practice to put your SqlConnection, SqlCommand and SqlDataReader into using(....) { .... } blocks to ensure proper disposal:
string connectionString = ".......";
string query = "INSERT INTO dbo.Person(birthdate) VALUES(#Birthdate);";
using (SqlConnection con = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand(query, conn))
{
cmd.Parameters.Add("#Birthdate", SqlDbType.Date).Value = dateTimePicker.Value.Date;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
As mentioned before the best practice is to use parameters, but if you really need to use a TSQL statement from source you should use date in the format: yyyymmdd
cmd.CommandText="INSERT INTO person (birthdate) VALUES('"+dateTimePicker.Value.Date.ToString("yyyyMMdd")+"')";
Try including quotes:
cmd.CommandText="INSERT INTO person (birthdate) VALUES('"+dateTimePicker.Value.Date+"')";
I'd recommend using parameters too.
Try this as string format:
cmd.CommandText="INSERT INTO person(birthdate)VALUES('"+dateTimePicker.Value.Date+"')";
dateTimePicker stores values as 1/1/1900 12:00:00 AM so you should use DATETIME if you're trying to store it since DATETIME's format is: YYYY-MM-DD HH:MI:SS.
You can print the dateTimePicker value using
MessageBox.Show(dateTimePicker.Value.ToString());
to see for yourself.
kindly let me know how to insert two variables. its not a problem giving directly my userid and mobile in the code like
string insert =#"Insert into userHistory(userid,mobile) values(x,y)";
This is my code, but it fails to insert (editors note: OP provided no error)
int userid = 123456;
long mobile = 91888888888;
sqlConn = new MySqlConnection(/* conn string removed */);
sqlConn.Open();
string insert =
#"Insert into userHistory(userid,mobile) values(#userid,#mobile);";
MySqlCommand cmd = new MySqlCommand(insert,sqlConn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new MySqlParameter("#userid", userid));
cmd.Parameters.Add(new MySqlParameter("#mobile", mobile));
Without more Information, I guess the type of your command should be "Text" and not CommandType.StoredProcedure, since you do not execute a SP. And you have to execute the command (maybe this is only missing in your code)
this is wrong cmd.CommandType = CommandType.StoredProcedure the command is should be CommandType.Text
You can read more about the CommandType enumeration here.
There are some more .net examples for MySql here
I think the issue is cmd.CommandType = CommandType.StoredProcedure;
You are trying to execute an ad-hoc query, not a Stored Procedure. Try changing it to
cmd.CommandType = CommandType.Text;