June 29, 2006 at 2:45 am
Hi,
I have an application that has been running for 5 years perfectly happily. It has occasionally thrown up untrapped errors that have just disappeared when moved to an alternate machine.
After much pain I have tracked this down to the implicit conversion of dates being passed to a stored procedure. The ADO command object builds a string that contains the date string in the format YYYYMMDD and the parameter datatype it is passed to is datetime. Because of what appears to be the inconsistent nature of this error does anyone now of any environmental settings that would affect the formatting of this datestring?
i am unable to amend the actual code to cure the ambiguous dates that are obviously possible using this method of type conversion due to a large number of interfaces based on the dates produced so really do need to track down the cause as a resolution.
Its SQL7, MDAC 2.5 SP1 and VB6.
thanks.
rodger
June 30, 2006 at 1:25 am
June 30, 2006 at 6:57 am
Dunno about VB datetimes but in SQL Server 2000...
I think you'll find that 23:59:59.999 will round up to precisely 00:00:00.000 and that 23:59:59.998 will round down to 23:59:59.997.
SELECT CAST('23:59:59.999' AS DATETIME)
SELECT CAST('23:59:59.998' AS DATETIME)
SELECT CAST('23:59:59.997' AS DATETIME)
...so the closest you can get to before mid-night is '23:59:59.998' and after mid-night is '00:00:00.002', otherwise '23:59:59.999' thru '00:00:00.001' = ''00:00:00.000' which IS NULL. |
Absolutely not true... I think you'll find that the time portion of a datetime is never NULL if a date is present and that a time of 00:00:00.000 IS possible and frequently used.
SELECT CAST('00:00:00.000' AS DATETIME)
SELECT CAST('20060630' AS DATETIME)
There is a slightly more confusing situation for the Date portion of a datetime, for SQL Server the Date portion of the datetime = '1/1/1900' means that is the "base date" and it IS NULL... The following from SQL Server SELECT CAST('' AS datetime) returns : 1900-01-01 00:00:00.000 Which means that both the Date and Time portions are NULL. |
A zero value is not the same as a NULL value... An empty string ('') is not the same as a NULL... NULL is not "Nothing"... NULL is NULL.
SELECT CAST(0 AS DATETIME)
SELECT CAST(NULL AS DATETIME)
SELECT CAST('' AS DATETIME)
...therefore a valid date is "12:00:01 AM" for midnight (or "00:00:00.002" for 24 hour format). |
That's absolutely not true... 12:00:01 AM is no more midnight than NULL is nothing...
SELECT CAST('00:00:00' AS DATETIME)
SELECT CAST('20060630' AS DATETIME)
SELECT CAST('00:00:00' AS SMALLDATETIME)
SELECT CAST('20060630' AS SMALLDATETIME)
I'm not sure what your source of information about dates, times, and NULLs is but you should check out what Books OnLine has to say.
By the way, there's an underlying "date serial" number for each date/time and it's based on the FLOAT datatype which is why certain times like 23:59:59:999 get rounded... FLOAT is one of those nasty "approximate" data types based on binary math. The numbers to the left of the decimal point represent the number of whole days since midnight 19000101 and the numbers to the right represent the number of fractional days which is interpreted as time... that's why the following produces a datetime of 2006-06-30 08:49:12.043 and 0 produces a date time of 1900-01-01 00:00:00.000... that's also why you cannot have a NULL time if a date is present... you cannot have a value of 38896.NULL, for example...
SELECT CAST(38896.367500501547 AS DATETIME)
SELECT CAST(0 AS DATETIME)
SELECT CAST(38896 AS DATETIME)
GO
SELECT CAST(38896.NULL AS DATETIME)
I do agree that ISO dates should always be used except for reporting purposes. More than that, if you have a world-wide presence, you should use UTC dates with offsets to produce local times.
--Jeff Moden
Change is inevitable... Change for the better is not.
June 30, 2006 at 7:06 am
Gents,
Many thanks for taking the time to respond but I cant have clearly defined my issue.
I have an ADO Connection object. The SQL statement is built as a string and includes all the input parameters for the SP that it is to execute. I am fully aware that a command object would have done this job better but need to understand why all of a sudden the string to datetime conversion of the input parameter has stopped working in my environment but continues to work in the Production environment. This code wasnt mine in the first place so its looking like a rewrite at present.
thanks.
Rodger
July 2, 2006 at 9:32 pm
Rodger,
Did anyone change the default datatime format on the non-production box?
This is why you should not trust defaults... things change.
Perhaps, if you posted the code, we may be able to better help.
--Jeff Moden
Change is inevitable... Change for the better is not.
July 3, 2006 at 2:14 am
As usual no one is admitting to changing anything.
With p_oCom
For l_lCounter = l_lLBound To l_lUBound
l_cData = p_vData(l_lCounter)
If Len(l_cData) = 0 Then
l_cData = ""
End If
Debug.Print .Parameters(l_lCounter).Type
Select Case p_aeValidation(l_lCounter).eType 'tValidation.eType
Case edtEntity.edtDate
If l_cData = "NULL" Then
l_cData = "19000101"
End If
If .Parameters(l_lCounter).Type = adDBTimeStamp Then
.Parameters(l_lCounter).Type = adDate
End If
.Parameters(l_lCounter).Value = DateSerial(CInt(Right(l_cData, 4)), CInt(Mid(l_cData, 3, 2)), CInt(Left(l_cData, 2)))
____________________________________________________
All the dates parameters are declared as datetime and all I get back from ADO is an Insertion Error.
Thanks.
Rodger
July 3, 2006 at 3:24 pm
Like you said, the code has been running fine except for the occasional hiccup... the problem must be in the data somewhere you are not trapping for an error.
--Jeff Moden
Change is inevitable... Change for the better is not.
July 5, 2006 at 4:04 am
Hi,
I have now resolved this by changing the call to the SP to use the Command object rather than Connection object. I narrowed the issue down to the conversion of the parameters in the string used in the Execute on the connection object. ie convert a date to a string then the Execute has to convert it back to a date. Command object means I pass a date to a date parameter and no conversion is required.
I inherited this horribly written bit of code and had to cobble a resolution together, thanks to all that took the time to respond.
Rodger
July 5, 2006 at 10:29 pm
Thank you for the feed back on your resolution! It's a keeper...
--Jeff Moden
Change is inevitable... Change for the better is not.
Viewing 9 posts - 1 through 8 (of 8 total)
You must be logged in to reply to this topic. Login to reply