I am trying to fetch the record of 3rd june of 2013 from my database which is made in ms access. Dates are stored in the format of dd/MM/yyyy, below is my query
AND (a.Date = #" + date + "#) ) order by e.E_ID asc
But the amazing thing is i have inserted a record on date of 03/06/2013 which is todays date, while it takes it as 6th march 2013, i have corrected my regional settings, still the same issue. Also in my query i am query for matching date i am using dd/MM/yyyy. Is this a bug from microsoft? please help
Dates are stored in the format of dd/MM/yyyy
I suspect they're not. I suspect they're stored in some native date/time format which is doubtless much more efficient than a 10 character string. (I'm assuming you're using an appropriate field type rather than varchar, for example.) It's important to differentiate between the inherent nature of the data and "how it gets displayed when converted to text".
But the amazing thing
I don't see this as amazing. I see it as a perfectly natural result of using string conversions unnecessarily. They almost always bite you in the end. You're not trying to represent a string - you're trying to represent a date. So use that type as far as you possibly can.
You should:
Use parameterized SQL for queries for many reasons - most importantly to avoid SQL injection attacks, but also to avoid unneccessary string conversions of this kind
Specify the parameter value as a DateTime, thus avoiding the string conversion
You haven't specified which provider type you're using - my guess is OleDbConnection etc. Generally if you look at the documentation for the Parameters property of the relevant command class, you'll find an appropriate example. For example, OleDbCommand.Parameters shows a parameterized query on an OleDbConnection. One thing worth noting from the docs:
The OLE DB .NET Provider does not support named parameters for passing parameters to an SQL statement or a stored procedure called by an OleDbCommand when CommandType is set to Text. In this case, the question mark (?) placeholder must be used. [...]
Therefore, the order in which OleDbParameter objects are added to the OleDbParameterCollection must directly correspond to the position of the question mark placeholder for the parameter in the command text.
Related
I have a program that is moving data between two tables in a database. For this, I am using a SQL query and the System.Data.SqlClient package.
All of a sudden, this query throws an error when executing.
SQLCommand.ExecuteNonQuery is throwing:
Conversion failed when converting date and/or time from character string.
I have isolated the line with the conversion to:
AND DATEDIFF(dd,GETDATE(),SUBSTRING(a.date, 1, 10))<14
where a.date is the datetime as varchar. The query is a INSERT-SELECT query, and if I run only the SELECT part, it works. Even more strange is that this query works perfectly fine to run in SSMS both with and without data found.
Have anyone else seen this case lately?
where a.date is the datetime as varchar.
well there's your main problem. If you are storing a date/time: use the appropriate storage type in the database. You have a wide range to choose from, for example date, smalldatetime, datetime and datetime2 - and: SQL Server will know how to correctly understand and work with that data.
Ultimately the problem here is that SUBSTRING(a.date, 1, 10) isn't giving a result that SQL Server understands as a date through implicit string conversion operations. This approach is a: inefficient, and b: brittle (especially between cultures), hence why you simply shouldn't do that. If you store the data appropriately: all the problems will go away.
However! You could also use CONVERT to tell SQL Server to interpret the string as a date/time, explicitly telling it the format you expect (as a number code), so that it stands a chance.
If your a.date (and substring) isn't in one of the supported formats: abandon all hope.
BTW; DATEDIFF(dd,GETDATE(),SUBSTRING(a.date, 1, 10))<14 is probably more efficiently done by way of calculating the start-date/end-date of your range once and just comparing with a comparison operator. GETDATE() won't change per row, so "14 days from now" won't change per row. This would make your query a lot more efficient, especially when combined with the correct date/time format - it becomes:
a.date <= #end -- or < #end, or > #end, or >= #end
which can use an index.
Interesting! "No changes has been made to the code, and no new data has entered the queried table since then."
So the question why it doesn't work as the same way really have a many choice for you
Your code just don't run into the problem date data before.
Application server have something changed like date region/culture so it affect the application way of seeing date when communicate with DB server
the 2. but from DB server e.g. Infra team upgrade/patch the DB server, the configuration is affect so this has problem with date format , update/patching Db cause the build-in functions too have upgraded behavior too!)
The statement in double-quote is false.
System.Data.SqlClient 's feature when process the query ?
and so on...
I think finding the causes just from this little information is the very difficult task.
From my little search ,you really should go diving into the query and data as the others tried to suggest.
Conversion failed when converting date and/or time from character string while inserting datetime
Overview
This question is a more specific version of this one:
sql server - performance hit when passing argument of C# type Int64 into T-SQL bigint stored procedure parameter
But I've noticed the same performance hit for other data types (and, in fact, in my case I'm not using any bigint types at all).
Here are some other questions that seem like they should cover the answer to this question, but I'm observing the opposite of what they indicate:
c# - When should "SqlDbType" and "size" be used when adding SqlCommand Parameters? - Stack Overflow
.net - What's the best method to pass parameters to SQLCommand? - Stack Overflow
Context
I've got some C# code for inserting data into a table. The code is itself data-driven in that some other data specifies the target table into which the data should be inserted. So, tho I could use dynamic SQL in a stored procedure, I've opted to generate dynamic SQL in my C# application.
The command text is always the same for row I insert so I generate it once, before inserting any rows. The command text is of the form:
INSERT SomeSchema.TargetTable ( Column1, Column2, Column3, ... )
VALUES ( SomeConstant, #p0, #p1, ... );
For each insert, I create an array of SqlParameter objects.
For the 'nvarchar' behavior, I'm just using the SqlParameter(string parameterName, object value) constructor method, and not setting any other properties explicitly.
For the 'degenerate' behavior, I was using the SqlParameter(string parameterName, SqlDbType dbType) constructor method and also setting the Size, Precision, and Scale properties as appropriate.
For both versions of the code, the value either passed to the constructor method or separately assigned to the Value property has a type of object.
The 'nvarchar' version of the code takes about 1-1.5 minutes. The 'degenerate' or 'type-specific' code takes longer than 9 minutes; so 6-9 times slower.
SQL Server Profiler doesn't reveal any obvious culprits. The type-specific code is generating what would seem like better SQL, i.e. a dynamic SQL command whose parameters contain the appropriate data type and type info.
Hypothesis
I suspect that, because I'm passing an object type value as the parameter value, the ADO.NET SQL Server client code is casting, converting, or otherwise validating the value before generating and sending the command to SQL Server. I'm surprised tho that the conversion from nvarchar to each of the relevant target table column types that SQL Server must be performing is so much faster than whatever the client code is doing.
Notes
I'm aware that SqlBulkCopy is probably the best-performing option for inserting large numbers of rows but I'm more curious why the 'nvarchar' case out-performs the 'type-specific' case, and my current code is fast enough as-is given the amount of data it routinely handles.
The answer does depend on the database you are running, but it has to do with the character encoding process. SQL Server introduced the NVarChar and NText field types to handle UTF encoded data. UTF also happens to be the internal string representation for the .NET CLR. NVarChar and NText don't have to be converted to another character encoding, which takes a very short but measurable amount of time.
Other databases allow you to define character encoding at the database level, and others let you define it on a column by column basis. The performance differences really depend on the driver.
Also important to note:
Inserting using a prepared statement emphasizes inefficiencies in converting to the database's internal format
This has no bearing on how efficient the database queries against a string--UTF-16 takes up more space than the default Windows-1252 encoding for Text and VarChar.
Of course, in a global application, UTF support is necessary
They're Not (but They're Almost as Fast)
My original discrepancy was entirely my fault. The way I was creating the SqlParameter objects for the 'degenerate' or 'type-specific' version of the code used an extra loop than the 'nvarchar' version of the code. Once I rewrote the type-specific code to use the same number of loops (one), the performance is almost the same. [About 1–2% slower now instead of 500-800% slower.]
A slightly modified version of the type-specific code is now a little faster; at least based on my (limited) testing – about 3-4% faster for ~37,000 command executions.
But it's still (a little) surprising that it's not even faster, as I'd expect SQL Server converting hundreds of nvarchar values to lots of other data types (for every execution) to be significantly slower than the C# code to add type info to the parameter objects. I'm guessing it's really hard to observe much difference because the time for SQL Server to convert the parameter values is fairly small relative to the time for all of the other code (including the SQL client code communicating with SQL Server).
One lesson I hope to remember is that it's very important to compare like with like.
Another seeming lesson is that SQL Server is pretty fast at converting text to its various other data types.
I'm working with C# and MySQL now. I've tried to search around the internet for day to find out why I can't use AddWithValue method to add unicode characters because when I manually add it in MySQL, it works! But back in the C# code with MySQL connector for .NET it doesn't work. Other than the unicode characters is fine.
cmd.CommandText = "INSERT INTO tb_osm VALUES (#id, #timestamp, #user)";
cmd.Parameters.AddWithValue("#id", osmobj.ID);
cmd.Parameters.AddWithValue("#timestamp", osmobj.TimeStamp);
cmd.Parameters.AddWithValue("#user", osmobj.User);
cmd.ExecuteNonQuery();
For example: osmbj.User = "ສະບາຍດີ", it will be "???????" in the database.
Please T^T
does this link help you?
read/write unicode data in MySql
Basically it says, you should append your connection string with charset=utf8;
Like so:
id=my_user;password=my_password;database=some_db123;charset=utf8;
You have to be sure that unicode characters are supported at every level of the process, all the way from the input into C# to the column stored in MySql.
The C# level is easy, because strings are already utf-16 by default. As long as you're not using some weird gui toolkit, reading from a bad file or network stream, or running in a weird console app environment with no unicode support, you'll be in good shape.
The next layer is the parameter definition. Here, you're better off avoiding the AddWithValue() method, anyway. The link pertains the Sql Server, but the same reasoning applies to MySql, even if MySql is less strict with your data than it should be. You should use an Add() override that lets you explicitly the declare the type of your parameters as NVarChar, instead of making the ADO.Net provider try to guess.
Next up is the connection between your application and the database. Here, you want to make sure to include the charset=utf8 clause (or better) as part of the connection string.
Then we need to think about the collation of the database itself. You have to be sure that an NVarChar column in MySql will be able to support your data. One of the answers from the question at previous link also covers how to handle this.
Finally, make sure the column is defined with the NVarChar type, instead of just VarChar.
Yes, utf8 at all stages -- byte-encoding in client, conversion on the wire (charset=utf8), and on the column. I do not know whether C# converts from utf16 to utf8 before exposing the characters; if it does not, then charset=utf16 (or no setting) may be the correct step.
Because you got multiple ?, the likely cause is trying to transform non-latin1 characters into a CHARACTER SET latin1 column. Since latin1 has no codes for Lao, ? was substituted. Probably you said nothing about the column, but depended on the DEFAULT on the table and/or database, which happened to be latin1.
The ສະບາຍດີ is lost and cannot be recovered from ???????.
Once you have changed things, check that it is stored correctly by doing SELECT col, HEX(col) .... For the string ສະບາຍດີ, you should get hex E0BAAAE0BAB0E0BA9AE0BAB2E0BA8DE0BA94E0BAB5. Notice how that is groups of E0BAxx, which is the range of utf8 values for Lao.
If you still have troubles, please provide the HEX for further analysis.
so i have a string "09/15/2014" and in c# it converts it to date:
DateTime from = Convert.ToDateTime(fromdate);
this outputs "9/15/2014" and when I send it over to sql I get this:
select convert(varchar, '9/1/2014 12:00:00 AM', 101)
which doesn't work for me because I need to keep any leading zero's.
help?
If you're worried about the string formats for dates with Sql Server, you're doing it wrong. As a comment to another answer indicates, SQL Server internally stores all dates in a machine-optimized numeric format that is not easily human-readable. It only converts them to a human-understandable format for output in your developer tools.
When sending dates to Sql Server, always use query parameters. In fact, when sending any data, of any type, to Sql Server in an SQL statement, always use query parameters. Anything else will not only result in formatting issues like your problem here, but will also leave you crazy-vulnerable to sql injection attacks. If you find yourself using string manipulation to include data of any type into an SQL string from client code, step away from the keyboard and go ask a real programmer how to do it right. If that sounds insulting, it's because it's so hard to understate the importance of this issue and the need to take it seriously.
When retrieving dates from Sql Server, most of the time you should just select the datetime field. Let client code worry about how to format it. Do you want leading zeros? Great! The Sql Datetime column will at some point be available in C# as a .Net DateTime value, and you can use the DateTime's .ToString() method or other formatting option to convert the value to whatever you want, at the client.
SQL queries use a date and time format which goes like this:
2014-09-15
That's year-month-day. As per the comments below, this may be different depending on the collation you have on your database (see Scott's comment for a more accurate way to describe this and get dates into this format).
DateTime's ToString method has an overload which takes a formatting string. So you can pass the format you want the string to be output to. Try it like this:
string queryDate = from.ToString("yyyy-MM-dd");
And see what you get. Use that on your query.
But if you really want this done right, use parameters. Like:
SqlCommand command = new Command(connection, "SELECT * FROM foo WHERE someDate = #date");
command.Parameters.AddWithValue("#date", from);
// where "from" is your DateTime variable from the code you've shown.
This will save you the trouble of DateTime to String conversions.
I'm trying to run a query from C# to MySQL (version 5.5.27) using the mysql connector for .net from the MySQL website.
The ultimate goal of the .dll I'm developing is to keep track of the rows that I've read.
The query I use to read the database is:
string strSQL = "SELECT date,ask,bid,volume FROM gbpjpy where `read` = 0";
To read in the date, I have:
DateTime dateTime = mysqlReader.GetDateTime(0);
That works fine.
The table has 5 columns, the last column is called "read". Right after the select query and parsing is done, I execute the following query:
string sqlFormattedDate = dateTime.ToString("yyyy/MM/dd HH:mm:ss");
string query = "UPDATE gbpjpy SET `read` = 1 WHERE `date` = " + sqlFormattedDate;
However, when I check my log, I have the following error:
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 '01:20:08' at line 1.
The first date read in is 2012/08/30 01:20:08 (that's how it appears in the MySQL table, so that's where it gets the 01:20:08).
I've tried var sqlFormattedDate, changing the ToString overload to yyyy-MM-dd (using dashes and not forward slashes) and dateTime.ToString() all to no avail.
Why is MySQL not picking up the entire string?
Basically you should avoid including values in your query directly.
No doubt you could put quotes around the value... but you shouldn't. Instead, you should use paramterized SQL, and put the value in the parameter. That way you don't an error-prone string conversion, you avoid SQL injection attacks (for string parameters), and you separate code from data.
(As an example of how subtly-broken this can be, your current code will use the "current culture"'s date and time separators - which may not be / and :. You could fix this by specifying CultureInfo.InvariantCulture... but it's best not to do the conversion at all.)
Look for documentation of a Parameters property on whatever Command type you're using (e.g. MySqlCommand.Parameters) which will hopefully give you examples. There may even be a tutorial section in the documentation for parameterized SQL. For example, this page may be what you're after.
I suppose you have to put the whole value for the date in quotes. If you actually concatenate your query, it would look like
UPDATE gbpjpy SET `read` = 1 WHERE `date` = yyyy/MM/dd HH:mm:ss
That equal sign will only take the value until the first space.
Instead, it should look like
UPDATE gbpjpy SET `read` = 1 WHERE `date` = 'yyyy/MM/dd HH:mm:ss'
This is the particular reason in this case, however, concatenating queries like this leads to a real possibility of SQL injection. As a rule of thumb, you shouldn't do it. You can use parameterized queries and there's probably an API of the .NET connector you are using to do that.
Putting the info in a parameter allows the code to format as it needs. Likely, your original issue may have stemmed from using slashes instead of dashes in your date format. I would assume that slashes can work, but most all of the documentation I've seen has dashes separating dates with MySqlDateTimes.