Conversion failed when converting date and/or time from character string

前端 未结 3 1783
慢半拍i
慢半拍i 2021-01-13 12:33

I have this query :

set IDENTITY_INSERT dbo.OtherData1 ON


INSERT INTO OtherData1 (OtherDataID, EmployeeID, OtherDate, OType, OSubject, StatementNo, Stateme         


        
相关标签:
3条回答
  • 2021-01-13 12:48

    Try to use 103 for the second convert as well

    0 讨论(0)
  • 2021-01-13 13:00

    ISDATE won't work since you cannot even specify a date format as you can with CONVERT. The following is a VERY elaborate test to reformat valid dates into YYYYMMDD for which ISDATE works predictably.

    with otherdata(StatementDate) as (
    select convert(varchar(10),'1/10/2011') union all
    select '28/2/2911' union all
    select '8/12/2011' union all
    select '13/13/2011' union all
    select '13/12/2011' union all
    select '12/13/2011' union all
    select '2/29/2011' union all
    select '29/2/2011' union all
    select '29/2/2012' union all
    select '2011-02-01' union all
    select '1/1/11' union all
    select '1/1/99' union all
    select '' union all
    select null)
    
    -- THE QUERY YOU NEED is below this line. The above virtually sets up a table
    -- without having to physically create it
    select
        statementdate,
        YYYYMMDDToTest,
        ISDate(YYYYMMDDToTest)
    from otherdata
    cross apply
           (
           select TheYear = case
           when not statementdate like '%[0-9]/%[0-9]/%[0-9][0-9]' then null
           when convert(int,replace(statementdate,'/','')) != replace(statementdate,'/','') then null
           when statementdate like '%[0-9]/%[0-9]/[0-9][0-9]' then
               case when RIGHT(statementdate,2) >=50
               then '19'+RIGHT(statementdate,2)
               else '20'+RIGHT(statementdate,2)
               end
           when statementdate like '%[0-9]/%[0-9]/[1-9][0-9][0-9][0-9]' then
               RIGHT(statementdate,4)
           end
           ) A
    cross apply
           (
           select YYYYMMDDToTest = case
           when TheYear is not null then
               TheYear
               + -- month
               right(100+SUBSTRING(statementdate, charindex('/',statementdate) +1,
               charindex('/',statementdate,charindex('/',statementdate)+1)-
               charindex('/',statementdate)-1),2)
               + -- day
               right(100+LEFT(statementdate, charindex('/', StatementDate) -1),2)
           end
           ) B
    WHERE ISDate(YYYYMMDDToTest) = 0
    

    Comment out the last line WHERE ISDate(YYYYMMDDToTest) = 0 to see what it does with each date.


    EDIT

    You can turn this into a function that replaces the ISDATE - but for the SPECIFIC format [d]d/[m]m/yyyy.

    create function dbo.superIs103Date(@any varchar(50))
    returns bit as begin
    declare @theyear varchar(10)
    set @TheYear = case
           when not @any like '%[0-9]/%[0-9]/%[0-9][0-9]' then null
           when convert(int,replace(@any,'/','')) != replace(@any,'/','') then null
           when @any like '%[0-9]/%[0-9]/[0-9][0-9]' then
               case when RIGHT(@any,2) >=50
               then '19'+RIGHT(@any,2)
               else '20'+RIGHT(@any,2)
               end
           when @any like '%[0-9]/%[0-9]/[1-9][0-9][0-9][0-9]' then
               RIGHT(@any,4)
           end
    declare @YYYYMMDDToTest varchar(50)
    set @YYYYMMDDToTest = case
           when @TheYear is not null then
               @TheYear
               + -- month
               right(100+SUBSTRING(@any, charindex('/',@any) +1,
               charindex('/',@any,charindex('/',@any)+1)-
               charindex('/',@any)-1),2)
               + -- day
               right(100+LEFT(@any, charindex('/', @any) -1),2)
           end
    return ISDate(@YYYYMMDDToTest)
    end
    GO
    
    -- example usage
    select dbo.superIs103Date('33/1/1700')
    -- returns 0
    
    0 讨论(0)
  • 2021-01-13 13:05

    This won't get all possible invalid dates (e.g. 30 February) but might help you find ones that need fixing.

    SELECT StatementDate 
     FROM OtherData
     WHERE StatementDate NOT LIKE '[0-3][0-9]/[0-1][0-9]/[1-2][0-9][0-9][0-9]'
      AND  StatementDate NOT LIKE '[1-9]/[0-1][0-9]/[1-2][0-9][0-9][0-9]'
      AND  StatementDate NOT LIKE '[0-3][0-9]/[1-9]/[1-2][0-9][0-9][0-9]'
      AND  StatementDate NOT LIKE '[1-9]/[1-9]/[1-2][0-9][0-9][0-9]'
    
    0 讨论(0)
提交回复
热议问题