【问题标题】:How to remove conversion failed date / time error from SQL Server?如何从 SQL Server 中删除转换失败的日期/时间错误?
【发布时间】:2021-06-15 17:17:51
【问题描述】:

我写了一个程序给我这个错误

消息 241,级别 16,状态 1,过程 SumByDay,第 7 行 [批处理开始第 36 行]
从字符串转换日期和/或时间时转换失败。

这是程序

ALTER PROCEDURE SumByDay (@IN_forDate AS DATE, @IN_sensID INT)
AS
BEGIN
    DECLARE @timeFrom DATETIME2;
    DECLARE @timeTo DATETIME2;
    DECLARE @rowCount INT = 0; -- SQLINES DEMO *** statement affected rows

    SET @timeFrom = concat(CAST(@IN_forDate AS DATETIME2) , CAST('00:00:00' AS TIME)); -- start of the day
    SET @timeTo = concat(CAST(@IN_forDate AS DATETIME2) , CAST('23:59:59.999999' AS TIME)); -- end of the day
       
    DELETE FROM TrafficPerDay 
    WHERE TrafficPerDay.sensorID = @IN_sensID 
      AND TrafficPerDay.sDay = @IN_forDate; -- SQLINES DEMO *** sts, delete it, and recreate with new data
       
    INSERT INTO TrafficPerDay(sensorID, sDay, Motorcycle, Car, Van, Bus, Coach, Truck, ArticulatedTruck, Semitruck, Pedestrian, [Unknown], sTotal)
        (SELECT 
             t.sensorID, @IN_forDate AS 'sDay',
             COUNT(CASE WHEN t.classId = 1 THEN 'id' END) 'Motorcycle',
             COUNT(CASE WHEN t.classId = 2 THEN 'id' END) 'Car',
             COUNT(CASE WHEN t.classId = 3 THEN 'id' END) 'Van',
             COUNT(CASE WHEN t.classId = 4 THEN 'id' END) 'Bus',  
             COUNT(CASE WHEN t.classId = 5 THEN 'id' END) 'Coach',
             COUNT(CASE WHEN t.classId = 6 THEN 'id' END) 'Truck',
             COUNT(CASE WHEN t.classId = 7 THEN 'id' END) 'ArticulatedTruck',
             COUNT(CASE WHEN t.classId = 8 THEN 'id' END) 'Semitruck',
             COUNT(CASE WHEN t.classId = 9 THEN 'id' END) 'Pedestrian',
             COUNT(CASE WHEN t.classId = 0 THEN 'id' END) 'Unknown',
             COUNT(t.id) AS 'sTotal'
         FROM 
             TrafficRecord t
         WHERE 
             t.time BETWEEN @timeFrom AND @timeTo AND t.sensorId = @IN_sensID 
         GROUP BY t.sensorID, t.time );
        
    -- SQLINES LICENSE FOR EVALUATION USE ONLY
    SELECT @rowCount = @@ROWCOUNT

    IF (@rowCount = 0) 
    BEGIN  -- SQLINES DEMO *** ed, insert zeros
        INSERT INTO TrafficPerDay(sensorID, sDay, Motorcycle, Car, Van, Bus, Coach, Truck, ArticulatedTruck, Semitruck, Pedestrian, [Unknown], sTotal)
        VALUES (@IN_sensID, @IN_forDate, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    END  
END

我正在执行这样的程序

exec SumByDay @IN_forDate = '2020-11-04', @IN_sensID = 1;

【问题讨论】:

    标签: sql sql-server sql-server-2008 stored-procedures sql-server-2012


    【解决方案1】:

    问题是您在第 7 行的连接,正如错误告诉您的那样,但您不需要那个。使用>=< 逻辑而不是BETWEEN

    ALTER PROCEDURE SumByDay (@IN_forDate AS date,
                              @IN_sensID int)
    AS
    BEGIN
        --DECLARE @timeFrom datetime2; -- No need for these
        --DECLARE @timeTo datetime2; -- No need for these
        DECLARE @rowCount int = 0; -- SQLINES DEMO *** statement affected rows
        --SET @timeFrom = CONCAT(CAST(@IN_forDate AS datetime2), CAST('00:00:00' AS time)); -- start of the day -- No need for these
        --SET @timeTo = CONCAT(CAST(@IN_forDate AS datetime2), CAST('23:59:59.999999' AS time)); -- end of the day -- No need for these
    
        DELETE FROM TrafficPerDay
        WHERE TrafficPerDay.sensorID = @IN_sensID
          AND TrafficPerDay.sDay = @IN_forDate; -- SQLINES DEMO ***
        --sts, delete it, and recreate with new data
    
        INSERT INTO TrafficPerDay (sensorID,sDay,Motorcycle,Car,Van,Bus,Coach,Truck,ArticulatedTruck,Semitruck,Pedestrian,[Unknown],sTotal)
        (SELECT t.sensorID,
                @IN_forDate AS sDay,
                COUNT(CASE WHEN t.classId = 1 THEN 'id' END) AS Motorcycle,
                COUNT(CASE WHEN t.classId = 2 THEN 'id' END) AS Car,
                COUNT(CASE WHEN t.classId = 3 THEN 'id' END) AS Van,
                COUNT(CASE WHEN t.classId = 4 THEN 'id' END) AS Bus,
                COUNT(CASE WHEN t.classId = 5 THEN 'id' END) AS Coach,
                COUNT(CASE WHEN t.classId = 6 THEN 'id' END) AS Truck,
                COUNT(CASE WHEN t.classId = 7 THEN 'id' END) AS ArticulatedTruck,
                COUNT(CASE WHEN t.classId = 8 THEN 'id' END) AS Semitruck,
                COUNT(CASE WHEN t.classId = 9 THEN 'id' END) AS Pedestrian,
                COUNT(CASE WHEN t.classId = 0 THEN 'id' END) AS Unknown,
                COUNT(t.id) AS sTotal
         FROM TrafficRecord t
         WHERE t.time >= @IN_forDate
           AND t.time < DATEADD(DAY, 1, @IN_forDate)
           AND t.sensorId = @IN_sensID
         GROUP BY t.sensorID,
                  t.time); --Should this be CONVERT(date,t.time),
                           --or considering that this is for a single day, removed?
                           --If not, then simply t.time = @IN_forDate would work
    
        -- SQLINES LICENSE FOR EVALUATION USE ONLY
        SELECT @rowCount = @@ROWCOUNT;
        IF (@rowCount = 0)
        BEGIN -- SQLINES DEMO *** ed, insert zeros
            INSERT INTO TrafficPerDay (sensorID,sDay,Motorcycle,Car,Van,Bus,Coach,Truck,ArticulatedTruck,Semitruck,Pedestrian,[Unknown],sTotal)
            VALUES (@IN_sensID, @IN_forDate, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
        END;
    END;
    

    【讨论】:

    • 请注意,我已对您的 GROUP BY 子句 @UtkarshMishra 添加了附加评论。我注意到t.time 在那里,这没有多大意义。
    • 时间是列名先生
    • 这里的时间不是默认功能
    • “时间是列名先生” 我知道,@UtkarshMishra。但是您的 WHERE 暗示 time 实际上是一个 Date and time 值,因此对 t.time 进行分组将为每个 Distinct 日期和时间值提供一个单独的行,不是特定的日期,您的SELECT 暗示您想要。
    • 这根本不是我要说的,@UtkarshMishra。阅读我的评论:"Should this be CONVERT(date,t.time), or considering that this is for a single day, removed? If not, then simply t.time = @IN_forDate would work"
    【解决方案2】:

    您的datetime2 值设置不正确。

    通过将时间连接到已经转换为datetime2 的日期,您试图将2021-03-18 00:00:00.000000000:00:00.0000000 之类的日期分配给@timeFrom - 显然不正确。

    只需@timeFrom=Concat(@IN_forDate, ' 00:00:00')

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多