views:

556

answers:

1

Hi,

I've inherited a mass of stored procedures that take as their only parameter a block of XML, the author then cracks it (using OPENXML) and then updates the a row.

I've come across a problem while updating a table that has datetime columns, the following is a snippet of data that currently fails:

declare @stuff nvarchar (max);

set @stuff =
'<Booking xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;  
  <UpdatedDateTime>2009-08-14T15:32:09.7240556+01:00</UpdatedDateTime>
</Booking>';

declare @iDoc int;

exec sp_xml_preparedocument @idoc OUTPUT, @stuff;

SELECT UpdatedDateTime
    FROM 
     OPENXML(@idoc, '/*')
    WITH
    (
     UpdatedDateTime datetime 'UpdatedDateTime'
    )

Running that causes the following error:

Msg 241, Level 16, State 1, Line 12

Conversion failed when converting datetime from character string.

How do I go about converting the datetime from the XML fragment into a SQL based date time?

Thanks

+1  A: 

try:

declare @stuff nvarchar (max);

    set @stuff =
    '<Booking xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;  
      <UpdatedDateTime>2009-08-14T15:32:09.7240556+01:00</UpdatedDateTime>
    </Booking>';

    declare @iDoc int;

    exec sp_xml_preparedocument @idoc OUTPUT, @stuff;

    SELECT CONVERT(datetime,REPLACE(LEFT(UpdatedDateTime,23),'T',' ')),RIGHT(UpdatedDateTime,6)
        ,CASE
             WHEN LEFT(RIGHT(UpdatedDateTime,6),1)='+' THEN DATEADD(hh,CONVERT(int,LEFT(RIGHT(UpdatedDateTime,5),2)),CONVERT(datetime,REPLACE(LEFT(UpdatedDateTime,23),'T',' ')))
             ELSE DATEADD(hh,-1*CONVERT(int,LEFT(RIGHT(UpdatedDateTime,5),2)),CONVERT(datetime,REPLACE(LEFT(UpdatedDateTime,23),'T',' ')))
         END

        FROM 
         OPENXML(@idoc, '/*')
        WITH
        (
         UpdatedDateTime varchar(100) 'UpdatedDateTime'
        )

results set:

----------------------- ------ -----------------------
2009-08-14 15:32:09.723 +01:00 2009-08-14 16:32:09.723

(1 row(s) affected)
KM
Good call, except that the SP this comes from is updating directly to the table. The UpdatedDateTime in this case is a datetime, not any kind of string.
Kieron
to make it work, you will need to remove the "T" and the "+" offset
KM
Problem seems deeper than that, <UpdatedDateTime>2009-08-14 15:32:09.7240556</UpdatedDateTime> causes the same problem.
Kieron
reduce the decimal to 3 places
KM
Removing the .7240556 works, but then you loose a whole bunch of precision.
Kieron
OK, so this works: <UpdatedDateTime>2009-08-14T15:32:09.724</UpdatedDateTime>
Kieron
see my edit, I add back the time offset (probably not the most efficient code, but it works) I used combinations of LEFT and RIGHT, because I'm not sure of the time format and if SUBSTRING would hit the proper place each time.
KM
Awesome, it's a one hit operation on one record, so it'll be fine from a performance POV. Thanks.
Kieron