Been running in problem lately with using a DateTime in a T-SQL INSERT INTO statement. Work fine on one machine but might not work on another and I guess this has to do with locale settings.
So if I have DateTime variable what is the safe way of using that in a SqlStatement string that it will always work regardless on local system settings?
Thanks
Use parameterized INSERT query.
Most likely, your code is assembling the SQL command string. That also makes your code vulnerable to SQL Injection.
You should use parameterized query as Adrian suggested.
Another possibility is to use an ISO 8601 string representation like described here which is independent of locale settings.
That would look like:
20110921 15:20:00
Either you use parametrized command/stored procedures where you create a parameter of type DateTime in the stored and assign it from .net code when you call the stored (so .NET and SQL will know they are working with a datetime and will never confuse/swap day and month), or you include a specific command on top of your insert commands and then format all dataetime strings with this pattern, for example:
SET DATEFORMAT dmy;
SET DATEFORMAT (Transact-SQL)
Related
I have format exception when i trying to add '9/30/2019 5:15:54 PM'(DD-MM-YYYY) to my database.
I'm already SET datestyle = 'ISO, DMY'. So now i can use it like:
INSERT INTO products(name, createdat) values ('test', '9/30/2019 5:15:54 PM')
I have the same SQL command in C# and PostgreSQL, but it works only in Postgre-pgAdmin(nice joke C#).
How can fix this error in C#?
Well if you insert a valid Postgres timestamp literal, it should work everywhere:
INSERT INTO products (name, createdat)
VALUES
('test', '2019-09-30 17:15:54'::timestamp);
Perhaps the setting you configured were only valid from the session originating from pgAdmin, but not with the Postgres driver which C# is using. In any case, the default Postgres timestamp literal is ISO compliant (your version is not), which is always a good thing.
I'd like to execute a stored procedure on an sql server 2014. The sql server is set up in German, the user used for connecting to the sql server has also configured German as language. If I try to execute the sql procedure or raw sql, I always get the error
varchar cannot be converted to datetime
even if I provide german datetime values. I've found out that it works if I prepend the sql text with the command SET DATEFORMAT dmy.
The problem is the same for ADO .NET as well as Entity framework. Setting the thread and ui culture to German also didn't help.
It seems that C# SQL Connection sets the culture to default (English) independently of thread culture, date format or sql server language.
Any ideas highly appreciated how to set the culture correctly - such that I don't need to send always SET DATEFORMAT dmy before the real sql text.
UPDATE
This is my code to call the sql stored procedure and pass the dates using the c# sql parameter.
SqlConnection sqlConnection = null;
try
{
// open connection to the database
sqlConnection = new SqlConnection(Convert.ToString(ConfigurationManager.ConnectionStrings[ProductivityAnalyzerDatabase.ConnectionStringName]));
sqlConnection.Open();
// setup command
var sqlCommand = new SqlCommand("UpdateEmployeeBalances", sqlConnection);
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.Parameters.Add(new SqlParameter("#employeeId", employeeId));
sqlCommand.Parameters.Add(new SqlParameter("#startDate", startDate));
sqlCommand.Parameters.Add(new SqlParameter("#endDate", endDate));
sqlCommand.ExecuteNonQuery();
}
finally
{
if (sqlConnection != null && sqlConnection.State == ConnectionState.Open)
{
sqlConnection.Close();
}
}
Date values are not stored with their display format.
The problem is that you send your dates to Sql Server as strings, thus forcing sql server to cast the strings to date values. unless you send your dates in ANSI-SQL format (yyyy-mm-dd) this casting might fail or yield unexpected results (is 04/02/2015 April 2nd or February 4th?)
The correct solution, as Steve mentioned in his comment, is to use c#'s DateTime structure as the value of the parameter for the stored procedure. (don't use ToString or anything like that.)
Note that the parameter should be declared as a date type (datetime, datetime2, or date) in the stored procedure itself.
Good day,
You can read more about this issue in this clog:
http://ariely.info/Blog/tabid/83/EntryId/161/Date-displaying-format-vs-Date-storing-format.aspx
in short (from the link above):
Implicit conversion of ambiguous date formats are interpreted according to the language of the connection or the collate of the query. Always keep and following rules, in order to make your work more compatible.
Using .Net you should use a type that is mapped correctly to the SQL Server types. Check this link: https://msdn.microsoft.com/en-us/library/cc716729%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
When you specify dates in DML queries, always use constants way that
are interpreted the same way for all language settings!
for example use format yyyymmdd as 20160227, Use explicit CONVERT statement with an explicit style parameter, Use escape clauses while using ADO, OLE DB, or ODBC.
Remember that those are only display formats. In the database the
data stored in the same way, no matter what is your language!
*datetime is stored as 4 bytes for the date + 4 bytes for the time, Datetime2 is a bit more complex since it is flexible. you can read more on the undocumented internal stored format here.
I hope this is useful :-)
I have a stored procedure which input is from the type datetime. i.e. I transfer the input
2014-01-13T16:55:03.370 ,while running the stored procedure from the sql server.
Now I want to execute a stored procedure from the application.So I tried to use parameter having System.DateTime type.Looks like it is not corresponds to sql datetime.
Which type should I use for that?
UPD.
I didn`t get the answer for my question. So I`ll try to make my question more clear.
In SQL SErver database tables the values of the type datetime are saved.I am writing a stored procedure which looks for this values .I mean I need to get a parameter from the user of the for yyyy-mm-ddThh:mm:ss:.mmmm
from MSDN:
GetDate() is a inbuilt function in sql, for c# you can use follwing:
DateTime CurrentDate;
CurrentDate = Convert.ToDateTime(DateTime.Now.ToString("dd-MMM-yyyy"));
I guess you can pass this variable through to the procedure call parameters?
or, search the site again and read: Function that creates a timestamp in c#
Here you can find samples on data time conversions between SQL and C#, depending
on the date data types you use
I have the following line code used to retrieve data from database:
DataTable newEquipmentTable = database.Connection.RetrieveData(database.AdapterType, string.Format("SELECT ID FROM Equipment WHERE Name = '{0}' AND CreatedOn = '{1}'", equipment.Name, equipment.CreatedOn.ToString("yyyy-MM-dd HH:mm:ss.fff")));
It returns an error saying "The conversion of varchar data type to a datetime datatype resulted in an out-of-range value"
When I make a direct consult, using the following query it returns the expected result.
SELECT ID FROM Equipment WHERE Name = 'aa' AND CreatedOn = '2012-04-17 19:42:49.650'
What am I doing wrong?
You're passing a String value to select a datetime field. So you need to convert it to a datetime first:
Convert(datetime,'2012-04-17 19:42:49.650', 102)
Apart from that you might be open for SQL-Injection as #Mr47 has mentioned, use SqlParameters.
Please note that SQL's datetime type cannot hold values prior to 1753-01-01.
Just inspect the SQL string with the debugger before it is used to query the database in order to find the problem.
However, the best thing to do is to use a parameterized query (like in this example); otherwise you're vulnerable to SQL Injection.
What is the value of equipment.CreatedOn?
I think problem with the culture setting either in sql-server or your application. It cannot directly covert your date. User culture setting will solve problem.
I am using Entity framework and have 1 field in database AddedDate that is DateTime and not null, so I need to pass DateTime value.
But the problem is I have to pass DB Server datetime. How can I manage in this sceario or how can I get DB Server datatime to pass this.
I need to some unique solution, because I am this on many forms.
Edit: I need DB server Datetime upon insertion/updation in my application so that I can pass to entity framework object.
Thanks
Since you are using entity framework, you can do something like this:
var dateQuery = yourDbContext.CreateQuery<DateTime>("CurrentDateTime() ");
DateTime dateFromSql = dateQuery .AsEnumerable().First();
In general, if you use the entity framework and you use DateTime in a field, it will automatically do the back/forth conversion for you, just the same way it does so for integers, doubles etc.
Unless you mean something special, i.e., a char[40] field that must be filled with a DateTime value of a particular format.
You can get database server date and time by running SELECT GETDATE()) script.
Consider you have a table with 4 colums - the first 3 being strings and the last datetime, You can solve your issue by issueing INSERT SQL like this:
INSERT INTO myTable VALUES ('x', 'y', 'z', SELECT GETDATE())
Can't you use a stored procedure so you can get DB server Datetime very easily.
Just use getdate() in your query. For example:
INSERT INTO your_table (AddedDate, ...other columns) VALUES (getdate(), ...other values)
This basically asks the server to insert its own current date into the field; there's no need for you to retrieve it locally.