I serialize my c# object to xml, then got varchar such as '2009-05-09T13:50:59.6361485+08:00'.
But SQL Server return following messgae: 'Result: Msg 241: Conversion failed when converting date and/or time -- from character string.'
after I execute following sql:
declare #msg xml
set #msg='<root><date>2009-05-09T13:50:59.6361485+08:00</date></root>'
select #msg.value(N'(//root/date/text())[1]','datetime')
Try this:
declare #msg xml
set #msg='<root><date>2009-05-09T13:50:59.6361485+08:00</date></root>'
select #msg.value(N'(xs:dateTime((//root/date/text())[1]))', 'datetime')
The problem is, the datetime format in your XML has more precision in the 'seconds' value than the value() function (and its underlying call to CAST or CONVERT) can handle. See http://msdn.microsoft.com/en-us/library/ms187928(SQL.90).aspx. Conversion type 126 and 127 require .mmm (3 digits of precision), whereas in your original value you have 7.
For debugging steps, consider this:
select #msg.value(N'(//root/date/text())[1]', 'varchar(100)')
> 2009-05-09T13:50:59.6361485+08:00
select #msg.value(N'(xs:dateTime((//root/date/text())[1]))', 'varchar(100)')
> 2009-05-09T05:50:59.636Z
Related
So I'm writing a quick console program to collect rows of data from an old MySql database my company has and push the rows to a new Sql database. The first 300 or so rows have been fine but all of a sudden I am getting a
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
I've tried a number of ways to convert my datetimes now even though there seems to be nothing wrong with the conversion when I put it in a select.
IE:
DECLARE #INPUT varchar(30) = '09/25/2010 04:55:47';
SELECT CONVERT(datetime, #INPUT, 101);`
outputs 2010-09-25 04:55:47.000.
The conversion error is only showing up in the full Sql insert:
DECLARE #INPUT varchar(30) = '09/25/2010 04:55:47';
INSERT INTO TABLE(A_BUNCH_OF_OTHER_COLUMNS, DATETIME_COLUMN, MORE_COLUMNS)
VALUES (A_BUNCH_OF_OTHER_VALUES, CONVERT(datetime, #INPUT, 101), MORE_VALUES);`
I see no reason that this isn't working and after asking some of my coworkers, they see nothing wrong with the Sql either.
EDIT: Fixed the INSERT to reflect the actual statement.
INSERT INTO TABLE(A_BUNCH_OF_OTHER_COLUMNS, CONVERT(datetime, #INPUT, 101), MORE_COLUMNS)
In this part you should specify the column of the table which you want to insert values to. You specified the CONVERT method which is not a column.
If this is SQL Server please add the tag. What is #DT ? Are any A_BUNCH_OF_OTHER_COLUMNS | A_BUNCH_OF_OTHER_VALUES DateTimes? if so the conversion issue is likely there. – Alex K.
Thats where my problem was, there are 3 other datetime fields that are operating times that run over 24 hrs
I am new at this so please bear with me. I am using SQL Server and am trying to transfer data from my XML document into SQL Server.
I have two questions.
Question #1: I have an error for 'where'. If I remove the where line completely the error moves onto 'session'.
Question #2: I want the aptly named datetime column to feature a datetime data type. When I look at the xml document though I see that there is a T for what datetime equals. I believe this T symbolizes the word time. I am worried that this T will cause problems since I have never seen the data type datetime in SQL Server having a letter in the middle of the date and time. Is this a possibility? If so what should I do? I assume that I will have to change my data type if there is a problem (what should it be changed to if so?). Changing the xml document itself to remove the T is not an option.
Here is the copy-paste of my query:
DECLARE #x xml
SELECT #x = p
FROM OPENROWSET
(BULK 'C:\Users\Owner\Documents\congress\House votes\114 congress 2015\Passage\705.xml; , SINGLE_BLOB) AS HouseVote705(p)
DECLARE #hdoc int
EXEC sp_xml_prepare document #hdoc OUTPUT, #x
SELECT *
FROM OPENXML (#hdoc, '/roll', 1)
WITH (
'where' char,
'session' tinyint,
'year' smallint,
roll smallint,
'datetime' datetime)
EXEC sp_xml_removedocument
Here is the copypaste of my xml document:
<roll where="house" session="114" datetime="2015-12-18T09:49:00-05:00"> </roll>
A screenshot of my query and the xml document I am working with.
To answer your first question, use [ ] brackets to wrap those reserved keywords, instead of handling these as strings. Like some already stated in the comments, try to avoid the use of keywords for attributes.
Also, as long as you don't have a XSD (xml schema definition) try to interpret types as little as possible. The [where] is definitely not a single character. And are you sure the session will always fit in a TINYINT?
For your second question, the datetime provided is in Iso8601 format. Just read it as a varchar and convert it afterwards.
Here is an example based on your screenshot:
DECLARE #x XML
SELECT #x = CAST(N'<roll where="house" session="114" year="2015" roll="705" source="house.gov" datetime="2015-12-18T09:49:00-05:00" updated="2016-12-25T10:03:32-05:00"/>' AS XML)
DECLARE #hdoc INT
EXEC sp_xml_preparedocument #hdoc OUTPUT, #x, '<roll xmlns:xyz="urn:MyNamespace"/>';
SELECT [where] AS DocWhere
, [session] AS DocSession
, [year] AS DocYear
, roll
, CONVERT(datetime2, [datetime], 126) AS DocDatetime
FROM OPENXML (#hdoc, '/roll', 1)
WITH (
[where] VARCHAR(MAX)
, [session] INT
, [year] INT
, [roll] INT
, [datetime] VARCHAR(30)
)
As in your other questions: FROM OPENXML is outdated and should not be used anymore (rare exceptions exist)...
Rather use the modern XML methods for this:
DECLARE #xml XML=
N'<roll where="house" session="114" datetime="2015-12-18T09:49:00-05:00"> </roll>';
SELECT #xml.value(N'(/roll/#where)[1]',N'nvarchar(max)') AS roll_where
,#xml.value(N'(/roll/#session)[1]',N'int') AS roll_session
,#xml.value(N'(/roll/#datetime)[1]',N'datetime') AS roll_datetime
The result
roll_where roll_session roll_datetime
house 114 2015-12-18 14:49:00.000
UPDATE hundreds of files...
If this is a one time action it doesn't matter how you do this. This can be slow, ugly and dirty - as long as your result is correct...
Do you have the file paths/names in a table or are they following a computable schema? It should be easy to use a CURSOR or a WHILE to work this down in a loop.
You can use the command which you use on top of your question to load the XML's content directly into the variable #xml and use SELECT a,b,... INTO #tmpTbl FROM... to write the content of all your files in one go into a staging table.
In most cases it is best, to create the whole statement as string (don't forget to double all quotes!) within your loop and use EXEC to execute this. Otherwise you'd get a problem with the file's path in OPENROWSET...
I want to insert a datetime value into a table (SQL Server) using the SQL query below
insert into table1(approvaldate)values(18-06-12 10:34:09 AM);
But I get this Error msg:
Incorrect syntax near '10'.
I tried it with the quotes
insert into table1(approvaldate)values('18-06-12 10:34:09 AM');
I get this error message
Cannot convert varchar to datetime
You will want to use the YYYYMMDD for unambiguous date determination in SQL Server.
insert into table1(approvaldate)values('20120618 10:34:09 AM');
If you are married to the dd-mm-yy hh:mm:ss xm format, you will need to use CONVERT with the specific style.
insert into table1 (approvaldate)
values (convert(datetime,'18-06-12 10:34:09 PM',5));
5 here is the style for Italian dates. Well, not just Italians, but that's the culture it's attributed to in Books Online.
A more language-independent choice for string literals is the international standard ISO 8601 format "YYYY-MM-DDThh:mm:ss". I used the SQL query below to test the format, and it does indeed work in all SQL languages in sys.syslanguages:
declare #sql nvarchar(4000)
declare #LangID smallint
declare #Alias sysname
declare #MaxLangID smallint
select #MaxLangID = max(langid) from sys.syslanguages
set #LangID = 0
while #LangID <= #MaxLangID
begin
select #Alias = alias
from sys.syslanguages
where langid = #LangID
if #Alias is not null
begin
begin try
set #sql = N'declare #TestLang table (langdate datetime)
set language ''' + #alias + N''';
insert into #TestLang (langdate)
values (''2012-06-18T10:34:09'')'
print 'Testing ' + #Alias
exec sp_executesql #sql
end try
begin catch
print 'Error in language ' + #Alias
print ERROR_MESSAGE()
end catch
end
select #LangID = min(langid)
from sys.syslanguages
where langid > #LangID
end
According to the String Literal Date and Time Formats section in Microsoft TechNet, the standard ANSI Standard SQL date format "YYYY-MM-DD hh:mm:ss" is supposed to be "multi-language". However, using the same query, the ANSI format does not work in all SQL languages.
For example, in Danish, you will many errors like the following:
Error in language Danish
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
If you want to build a query in C# to run on SQL Server, and you need to pass a date in the ISO 8601 format, use the Sortable "s" format specifier:
string.Format("select convert(datetime2, '{0:s}'", DateTime.Now);
Management studio creates scripts like:
insert table1 (foodate) values(CAST(N'2012-06-18 10:34:09.000' AS DateTime))
you need to add it like
insert into table1(date1) values('12-mar-2013');
No need to use convert. Simply list it as a quoted date in ISO 8601 format.
Like so:
select * from table1 where somedate between '2000/01/01' and '2099/12/31'
The separator needs to be a / and it needs to be surrounded by single ' quotes.
If you are storing values via any programming language
Here is an example in C#
To store date you have to convert it first and then store it
insert table1 (foodate)
values (FooDate.ToString("MM/dd/yyyy"));
FooDate is datetime variable which contains your date in your format.
I encounter into a more generic problem: getting different (and not necessarily known) datetime formats and insert them into datetime column. I've solved it using this statement, which was finally became a scalar function (relevant for ODBC canonical, american, ANSI and british\franch date style - can be expanded):
insert into <tableName>(<dateTime column>) values(coalesce
(TRY_CONVERT(datetime, <DateString, 121), TRY_CONVERT(datetime, <DateString>,
101), TRY_CONVERT(datetime, <DateString>, 102), TRY_CONVERT(datetime,
<DateString>, 103)))
If the format of the date is as follows in sql : (datetime,null)
1
You can also use the "CAST" keyword
(CAST('2015-12-25 15:32:06.427' AS DateTime))
Just make sure that the date is in the correct format
I have existing datatables that include a field of hexadecimal data which is actually a date.
From existing code, I know that data is converted to a DATETIME values with:
SELECT CAST(0x0000214900000000 AS DATETIME)
My problem now is that I need to insert values into such fields manually, but I don't know how to generate the hexadecimal value for a given DATETIME.
I have tried to insert AS BINARY(8) but that does not return the correct value like above.
How do I perform this conversion?
If you are doing this ALL in SQL here is a simple example that exists all in memory. You can run this as is in SQL Management Studio and the syntax should be fine for 2008 SQL Server and up.
DECLARE
#Date DateTime = getdate()
, #Hex varbinary(8)
;
DECLARE #Temp TABLE ( value varbinary(8) );
INSERT INTO #Temp VALUES (0x0000214900000000),(cast(#Date AS varbinary));
Select
value
, cast(value AS DateTime)
from #Temp
SELECT #Hex = cast(cast('2015-04-01' AS DateTime) AS varbinary)
INSERT INTO #Temp VALUES (#Hex)
Select
value
, cast(value AS DateTime)
from #Temp
You basically 'cast' an object type to a different object. Yet for varbinary if you are storing this you need to specify a length as well. You can cast back and forth in SQL quite easily if the type conversion is allowed. If you wanted to do this for insertion from .NET code directly that may be slightly different.
I need your help in small problem, I have a column (data type timestamp) in SQL Server 2008.
Now I want to show this timestamp value in ASP.Net C# app as string. Is there any way to do that?
I tried it using regular data fetching in ASP.Net but it produced System.byte[] as output rather than actual value. In SQL Server Management Studio values are represented as 0x000000000000B3C0.
One option is to change it to the Date, while getting from the database. Like:
SELECT timestamp = DATEDIFF(s, '19700101', yourTimestampColumn)
FROM yourTable
I don't know if i catch you, but in sql you can cast timestamp value to datetime then to varchar like this:
declare #val timestamp = 0x0000AAE200B29565
select cast(cast(#val as datetime) as varchar(max))