ive got problem with my program, i got error in cmd.ExecuteNonQuery();, telling me "Data type mismatch in criteria expression."
using (OleDbConnection myCons = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=QuizDatabase.accdb"))
{
OleDbCommand cmd = new OleDbCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "insert into HighScores ([ID],[Name],[Score]) values (?,?,?)";
cmd.Parameters.AddWithValue("#ID", id.Text);
cmd.Parameters.AddWithValue("#Name", name.Text);
cmd.Parameters.AddWithValue("#Score", score.Text);
cmd.Connection = myCons;
myCons.Open();
cmd.ExecuteNonQuery();
myCons.Close();
}
thanks in advance! i really appreaciate fast response :)
thanks!! Steve for the help!
AddWithValue is really handy, but could lead to errors. If any of your fields is of numeric type you need to convert to the appropriate type the value that you pass to AddWithValue. As it stands now your code passes all strings. Probably you need
cmd.Parameters.AddWithValue("#ID", Convert.ToInt32(id.Text));
cmd.Parameters.AddWithValue("#Name", name.Text);
cmd.Parameters.AddWithValue("#Score", Convert.ToInt32(score.Text));
By the way. If the ID column is an Autonumber column you should avoid to pass that value.
I concur with Jon Skeet about that it is better to avoid AddWithValue (and you should avoid it with Sql Server and other optimizing database engine). AddWithValue cannot accurately convert your input values to the underlying database type.
This is a very interesting article
How Data Access Code Affects Database Performance
I suspect this is the problem:
cmd.Parameters.AddWithValue("#Score", score.Text);
I would expect a score to be a numeric field, so something like:
cmd.Parameters.Add("#Score", OleDbType.Integer).Value = numericScore;
... where numericScore is a variable of type int (or whatever's appropriate).
The same might be true for Id as well - we don't know what the field type is. Basically, you should try to make the parameter types match up with the field types as closely as possible. If you need to do any string conversion (e.g. parsing the value in a text box) I'd strongly recommend doing that in the .NET code rather than leaving it to the database.
(While you could still use AddWithValue, I believe it's a better idea to explicitly specify the type in the Add call and then set the value.)
Related
It always saves the date column in the database like this: 2016-10-16 00:00:00.000. And I want it saved like this: 2016-10-16 14:13:56.000.
I cannot save the time information to the database. The data type of date column in the database is also defined as datetime.
RecordDate(datetime,null)
When I debug the code, date shows "2016.10.16 14:13:56".
using (var conn = new SqlConnection())
{
conn.ConnectionString = connectionDBString;
conn.Open();
using (var command = conn.CreateCommand())
{
command.CommandText = $"INSERT INTO RECORDS VALUES('{records.Id}','{records.Type}','{records.Title}', #P0)";
if (records.Date != null)
{
command.Parameters.AddWithValue("P0", records.Date.Value);
}
command.ExecuteNonQuery();
}
conn.Close();
}
Type of records.Date is
DateTime?
Always parameterize all your values:
using (var command = conn.CreateCommand())
{
command.CommandText = $"INSERT INTO RECORDS VALUES(#id,#ty,#ti, #d)";
command.Parameters.Add("#id", SqlDbType.VarChar, 50).Value = records.Id);
command.Parameters.Add("#ty", SqlDbType.VarChar, 50).Value = records.Type);
command.Parameters.Add("#ti", SqlDbType.VarChar, 50).Value = records.Title);
//remove this line when you’re satisfied that the inserting of times does work
records.Date = DateTime.Now;
command.Parameters.Add(new SqlParameter("#d", SqlDbType.DateTime2) { Scale = 3, Value = (object)records.Date ?? DBNull.Value });
}
I have ..
guessed you are using sql server, but if you aren’t you’ll need to use different names for the type enum than SqlDbType, which is for sql server
specified all the parameters, which you should always do because not doing so is a bad idea
switched away from using AddWithValue, because it’s a bad idea for sql server but it’s not a problem for some other DB; investigate whether it’s a good idea for you
guessed at the column types from what you said and coded. I do not believe id to actually be a string, but you put it in ' in the statement - don’t just blindly write things in ' if they aren’t strings in the db. Change the types and sizes specified to match what your columns actually are
added a test line that sets your records.Date to a date time with a time. Don’t run the code bang on midnight :) - if your property isn’t writable, make it so or swap it out out the Value and put DateTime.Now in. I assumed record.Date was a typo
If your db column is a DateTime then this code will certainly insert a date and time
Omitting the column name list from INSERT will work while your table has 4 columns but if it changes and you add another the query will fail. This is either a good thing or a bad thing. Good if you want to stop your system working while you fix the problem, bad if your new column is optional and everything could have carried on working if you’d just specified the column names. Generally it makes more sense to specify names but if you’re wanting to code more efficiently consider moving away from this style of coding, where you’re writing your own SQL, and use Entity Framework
I was looking up how to insert into my database via sql and I noticed the way I had seen a person do an sql statement was different from the way I had done it and and now I'm wondering which way is better.
An example of what I had done in a previous (select) statement.
SqlConnection conn = new SqlConnection(Variables.Default.sqlConString);
conn.Open();
string builtCmd = Variables.Default.returnUserNameSql1 + usersInput + Variables.Default.returnUsernameSql2;
SqlCommand cmd = new SqlCommand(builtCmd, conn);
usersInput is a string.
Variables.Default.returnUserNameSql1 = SELECT [Username] from [dbo].[LoginDetails] WHERE [Username] = '
returnUsernameSql2 = '
What I have seen online (not my query):
cmd.CommandText = "INSERT INTO klant(klant_id,naam,voornaam) VALUES(#param1,#param2,#param3)";
cmd.Parameters.Add(new SqlParameter("#param1", klantId));
cmd.Parameters.Add(new SqlParameter("#param2", klantNaam));
cmd.Parameters.Add(new SqlParameter("#param3", klantVoornaam));
Is the use of the Parameters function (?) better? If so in what way?
Thanks for your time.
I modified my original query thanks to the help of some of the comments here. I'll post it if anyone's interested:
using (SqlConnection conn = new SqlConnection(Variables.Default.sqlConString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(Variables.Default.returnUserNameSql, conn))
{
cmd.Parameters.Add(new SqlParameter(Variables.Default.param1, usersInput));
SqlDataReader reader = cmd.ExecuteReader();
usernameTaken = reader.Read();
cmd.Dispose();
}
conn.Close();
}
Look up "SQL Injection attack" on google. Bobby Tables says hello. And then realize that your way is not bad, it is a security nightmare because everyone with access to your program can execute whatever SQL he wants.
SQL Injection is certainly an important reason not to use string concatenation, but there are a few others:
string delimiters - you'd need to include string delimiters in your SQL statement, and if the values you concatenate include them as well, you'll likely get syntax errors. With parameters you don't need string delimiters, and values with apostro[phes or quotes don't affect the SQL syntax.
string conversion of values - you'd need to convert all non-string values (numbers, dates, etc.) to strings, and ensure that their string represenatations are exactly reversible by the server. This is especially problematic for dates since the same string can represent two different dates depending on the culture of the server. With parameters, the values are passed without translation, so there's no risk that the server misinterprets values.
pre-compilation - with concatenation, the server must reanalyze each query to determine the "best" plan. With parameters, the server can re-use a cached plan since the actual query has been issued before, just with different parameters. This doesn't mean that queries will always perform faster, and in some cases can actually cause bad plans to be used, but it is a consideration if you issue millions of queries that only differ in parameter values.
I am getting an exception:
Incorrect syntax near ','.
in following query: please help.
I have tried it in many ways but not it does not work. Even when I try to insert a single value I still get this exception.
cmd = new SqlCommand("insert into purchaseOrder_master(sup_id,po_date,required_date,tot_amt,uid,potime) values("+supid.Text +",'"+podate.Value.Date+"','"+reqdate.Value.Date+"',"+pocost.Text +","+uid.Text +",'"+potime.Value.TimeOfDay +"')", con);
How often do we have to repeat that you should use parameterized queries?!
using (SqlCommand cmd = new SqlCommand("insert into table (column) values (#param)", conn))
{
cmd.Parameters.AddWithValue("#param", value);
cmd.ExecuteNonQuery();
}
The problems with your code are:
Wide open to SQL injections
DateTime values will not be handled correctly (probably the problem right now)
Strings must be handled properly (quotes)
cmd = new SqlCommand("insert into PurchaseOrder_master(sup_id) values(#val)", con);
cmd.parameters.AddWithValue("#val", supid.Text );
please check data type of date as well. it seems you passing just string for this. if its date time then you need parse string to datetime.
for that conversion use,
DateTime.Parse("stringValue");
if you want to save it without command parameters, then convert your date value and check as mentioned above.
Check out your actual SQL string.
Probably one of your values is an empty string.
That, and what Thorsten said. Use parametrized queries.
i believe the problem is you are putting strings in the insert statement without "'" signs
try:
cmd = new SqlCommand("insert into purchaseOrder_master(sup_id,po_date,required_date,tot_amt,uid,potime) values("+supid.Text +",'"+podate.Value.Date+"','"+reqdate.Value.Date+"','"+pocost.Text +"','"+uid.Text +"','"+potime.Value.TimeOfDay +"')", con);
as you can read here, when doing insert statement, every string needs to be surround with "'"
Try debugging your code and check what exactly the query is formed.
Also i think the possible reason is
insert into purchaseOrder_master(sup_id,po_date,required_date,tot_amt,**uid**,potime
uid is a keyword. replace it with [uid] and check
Change
"+uid.Text +"
to
'"+uid.Text +"'
and
"+supid.Text +"
to
'"+supid.Text +"'
so that
values("+supid.Text +",'"+podate.Value.Date+"','"+reqdate.Value.Date+"',"+pocost.Text +","+uid.Text +",'"+potime.Value.TimeOfDay +"')
reads
values('"+supid.Text +"','"+podate.Value.Date+"','"+reqdate.Value.Date+"',"+pocost.Text +",'"+uid.Text +"','"+potime.Value.TimeOfDay +"')
You have a string.empty in yours variables. Suddenly you generate the following commande :
insert into purchaseOrder_master(sup_id,po_date,required_date,tot_amt,uid,potime) values('value1','value2',,'value3'...
you can use string.format to format your command
Below is an insert statement that is inputting the first value (acctNum) into the second column (itemCode) and vice versa:
string addUpcCode = "INSERT INTO compare1 (acct, itemcode)"
+ "VALUES ('"+acctNum+"', '"+itemCode+"')";
This is not how I want it to work, as I want the first value to go in the first column and the second in the second column. How can I go about this?
Side note: This is a rough draft until I learn more about parameterization. I won't be releasing this code until I learn and implement it.
The given SQL snipplet will do what you want - especially the sequence of columns will be preserved.
I suspect you might have switched your variables, leading to the same phenomen but out of an other reason.
You should use SQL Parameters which also avoids creating a SQL injection problem:
using (SqlCommand command = new SqlCommand("INSERT INTO compare1 (acct, itemcode) VALUES (#AcctNum, #ItemCode)", connection))
{
// Add new SqlParameter to the command.
command.Parameters.Add(new SqlParameter("AcctNum", acctNum));
command.Parameters.Add(new SqlParameter("ItemCode", itemCode));
As you're using C# the string.format function is perfect for this kind of thing
string.format("INSERT INTO compare1(acct, itemCode) Values('{0}','{1}'", acctNum, itemCode);
or
string.format("INSERT INTO compare1 SELECT '{0}','{1}' ", acctNum, itemCode);
But yeah, you probably have them mixed up somewhere else, the order will be kept. Oh and if acctNum is an integer, you won't need the quotation marks around {0}
Edit:
Oh and yeah, definitely look into parameters next
Use parametrized queries to prevent SQL injection and you can solve this matter
command.Parameters.Add("AcctNum", acctNum);
I'm using Sqlite as my database of choice in a C# forms app, with http://sqlite.phxsoftware.com/ System.Data.SQLite provider. I'm trying to implement a search function, but it's not playing nice... or I'm missing something.
The simplified sql I'm using looks like this:
SELECT *
FROM Table
WHERE column LIKE #boundParameter ESCAPE '!'
When I run this, in any permutation with a parameter (using ? or ?001 or :boundParameter or #boundParameter), it gives me a FormatException: "Input string was not in a correct format." I haven't been able to find anything that says I can't use parameters with LIKE. Anyone know something about this? Do I need to do it some other way?
I would recommend trying something like this:
"SELECT * FROM [Table] WHERE [column] LIKE #boundParameter ESCAPE #escape";
and then:
command.Parameters.AddWithValue("#boundParameter", parameter));
command.Parameters.AddWithValue("#escape", "!");
Parameters.AddWithValue is the SQLite way of adding a bound parameter, rather than having to declare a new one each time.
#Noah (sorry, can't comment yet)
Stephen Jennings is right, you don't have to quote the value you are binding.
How do you connect and add parameters?
I haven't been using SQLite much, but the following should work;
SQLiteCommand command = _yourConnection.CreateCommand();
command.CommandType = CommandType.Text;
command.CommandText = "SELECT * FROM Table WHERE column LIKE #boundParameter";
command.Parameters.Add(new SQLiteParameter("#boundParameter", _yourSearchCriteria));
...
"Input string was not in a correct format" is not an error message returned by any version of SQLite
It must be being returned by the wrapper. SO ... I am going to guess that you are using the ADO.NET 2.0 Provider from sqlite.phxsoftware.com
You must remember to quote the value you are binding to the parameter.
For example, if you use
command.Parameters.Add(new SQLiteParameter("#boundParameter", _pattern));
then _pattern = "'test'" and not "test"
This program-code executes a query, that includes PARAMETER SUBSTITUTION and PATTERN FITTING in one step. Here, the string variable myNamePattern is the string that we wanna find the customers for, so that all returned customers will INCLUDE THE variable myNameattern string. I had the same problem, but i solved it! This is the perfect way, to substitute a string pattern (that is also a parameter) into SQLiteCommand.CommandText:
SQLiteCommand command = conn.CreateCommand();
command.CommandText = "select * from Customer where name like #myStringParameter";
command.Parameters.Add("myStringParameter", System.Data.DbType.String).Value = "%"+ myNamePattern+ "%";