【问题标题】:Can't find the error on a T-SQL Stored Procedure | Dim Date Populating Script在 T-SQL 存储过程中找不到错误 |暗淡日期填充脚本
【发布时间】:2020-04-11 16:31:45
【问题描述】:

这是我的程序:

ALTER PROCEDURE [dbo].[sp_ETL Populate Dim Date]
    @start_date NVARCHAR(10) = N'2009-01-01',
    @end_date NVARCHAR(10) = N'2010-12-31'
AS

TRUNCATE TABLE [STG Dim Date]

Declare
 @Date date,
 @endDate date,
 @IsLeapYear BIT,
 @IsWeekend BIT

Set @Date = @start_date
Set @endDate = @end_date

-- Loop through dates until end date
WHILE @Date <=@endDate
BEGIN
LINENO 0
-- Check for leap year
    IF ((Year(@Date) % 4 = 0) AND (Year(@Date) % 100 != 0 OR Year(@Date) % 400 = 0))
    BEGIN
        SELECT @IsLeapYear = 1
    END
    ELSE
    BEGIN
        SELECT @IsLeapYear = 0
    END
-- Check for weekend
    IF (DATEPART(dw, @Date) = 6 OR DATEPART(dw, @Date) = 7)
    BEGIN
        SELECT @IsWeekend = 1
    END
    ELSE
    BEGIN
        SELECT @IsWeekend = 0
    END
-- Insert data in dim date table
    INSERT Into [Baraam Retail STG].[dbo].[STG Dim Date]
    (
      [DateKey],         
      [Date],
      [DateString],
      [DayofMonth],
      [DayofYear],
      [DayofWeek],
      [DayofWeeknameENG],
      [DayofWeeknameHEB],
      [Week],
      [Month],
      [MonthNameENG],
      [MonthNameHEB],
      [MonthYear],
      [Qrt],
      [Qrt Name],
      [Year],
      [IsWeekend],
      [IsLeapYear]
    )
    Values
    (
    YEAR(@Date)*10000+MONTH(@Date)*100+DAY(@Date), -- DateKey | yyyymmdd
    @Date, -- Date |  yyyy-mm-dd 
    CONVERT(nvarchar(10), @Date, 105), -- DateString | dd-mm-yyyy
    Day(@Date), -- Day of Month | 1-31
    DATEPART(dy, @Date), -- Day of Year
    DATEPART(dw, @Date), -- Day of Week
    DATENAME(dw, @Date), -- English Day of Week Name
    CASE DATEPART(dw, @Date) -- Hebrew Day of Week Name
        WHEN 1 THEN N'ראשון'
        WHEN 2 THEN N'שני'
        WHEN 3 THEN N'שלישי'
        WHEN 4 THEN N'רביע'
        WHEN 5 THEN N'חמישי'
        WHEN 6 THEN N'שישי'
        WHEN 7 THEN N'שבת'
    END,
    DATEPART(wk, @Date), -- Week of Year
    DATEPART(mm, @Date), -- Month of Year | 1-12
    DATENAME(mm, @Date), -- English Month of Year Name 
    CASE DATEPART(mm, @Date) -- Hebrew Month of Year Name 
        WHEN 1 THEN N'ינואר'
        WHEN 2 THEN N'פברואר'
        WHEN 3 THEN N'מרצ'
        WHEN 4 THEN N'אפריל'
        WHEN 5 THEN N'מאי'
        WHEN 6 THEN N'יוני'
        WHEN 7 THEN N'יולי'
        WHEN 8 THEN N'אוגוסט'
        WHEN 9 THEN N'ספטמבר'
        WHEN 10 THEN N'אוקטובר'
        WHEN 11 THEN N'נובמבר'
        WHEN 12 THEN N'דצמבר'
    END,
    CONCAT(RIGHT(('0'+CAST(MONTH(@Date)AS VARCHAR(2))),2),'-',YEAR(@Date)), -- Month Year | mm-yyyy
    DATENAME(qq, @Date), -- Qrt
    CASE DATEPART(qq, @Date) -- Qrt Name
        WHEN 1 THEN N'Q-1'
        WHEN 2 THEN N'Q-2'
        WHEN 3 THEN N'Q-3'
        WHEN 4 THEN N'Q-4'
    END,
    Year(@Date),
    @IsWeekend,
    @IsLeapYear 
    )
    -- Step to next day
    SET @Date = DATEADD(dd, 1, @Date)
END
-- Join Holidays
UPDATE [Baraam Retail STG].[dbo].[STG Dim Date]
SET 
    [HolidayName] = ISNULL([Baraam Retail STG].[dbo].[STG Hashing Holidays].[Period], N'יום חול'),
    [IsHoliday] = 
     CASE WHEN [Baraam Retail STG].[dbo].[STG Hashing Holidays].[Period] IS NULL
        THEN 0
        ELSE 1
     END
FROM [STG Dim Date] LEFT JOIN [Baraam Retail STG].[dbo].[STG Hashing Holidays]
ON [STG Dim Date].[Date] BETWEEN [STG Hashing Holidays].[Begining] AND [STG Hashing Holidays].[End]

基本上,proc 得到一个起始日期和结束日期。它填充了一个 Dim 日期表。

我正在通过这个脚本执行它:

EXEC [sp_ETL Populate Dim Date]
@start_date = '2009-01-01',
@end_date = '2010-12-31'

我收到一条错误消息:

消息 241,级别 16,状态 1,过程 sp_ETL 填充暗淡日期,行 20 [Batch Start Line 0] 转换日期和/或时转换失败 字符串的时间。

我使用这个脚本来创建 Dim Date 表:

CREATE TABLE [Baraam Retail STG].[dbo].[STG Dim Date]
(
  [DateKey]             INT,         
  [Date]                DATE,
  [DateString]          DATE,
  [DayofMonth]          BIT,
  [DayofYear]           SMALLINT,
  [DayofWeek]           TINYINT,
  [DayofWeeknameENG]    VARCHAR(10),
  [DayofWeeknameHEB]    VARCHAR(10),
  [Week]                TINYINT,
  [Month]               TINYINT,
  [MonthNameENG]        VARCHAR(10),
  [MonthNameHEB]        VARCHAR(10),
  [MonthYear]           CHAR(7),
  [Qrt]                 TINYINT,
  [Qrt Name]            CHAR(7),
  [Year]                SMALLINT,
  [IsWeekend]           BIT,
  [IsLeapYear]          BIT,
  [IsHoliday]           BIT,
  [HolidayName]         VARCHAR(50)
)

通过检查 Dim Date 表中的输出,proc 启动并循环 12 个日期(2019-01-01 到 2019-01-12)。所有输出都是正确的。它在 2019-01-13 停止。我为每个计算创建了一个打印命令,它似乎运行良好。

我的 SSMS 版本没有调试器。所以我不能用它来调试问题。

你怎么看?

【问题讨论】:

  • 仅将此CONVERT(nvarchar(10), @Date, 105), -- DateString | dd-mm-yyyy 更改为@Date,表示无需转换
  • 问题可能是目标表中的DateString 列具有数据类型date - 它应该具有nvarchar(10) 以匹配插入的数据。目前字符串被隐式转换回date
  • 仅供参考,sp_ 前缀由 Microsoft 保留用于 S 特殊 P程序。建议不要将其用于用户存储过程,因为它会带来性能成本,并且如果 Microsoft 曾经实施具有相同名称的特殊过程,您的过程可能会停止工作。 Is the sp_ prefix still a no-no?
  • 非常感谢!问题在于 ```DateString`` 列。目标列数据类型错误。
  • 当你 asked a rubber duck 好奇从 2019-01-01 到 2019-01-12 并在 2019-01-13 失败时,鸭子有没有问第 13 个月是什么? - 希伯来日历? YYYY-MM-DDYYYY-DD-MM 日期之间的混淆是很常见的,而鸭子非常适应这种差异。

标签: sql-server tsql stored-procedures dimensions


【解决方案1】:

问题肯定是分配表达式

CONVERT(nvarchar(10), @Date, 105)

到 DATESTR 字段。目前尚不清楚您要在这里完成什么,但 SQL Server 不一定能够将此字符串解析为日期。

【讨论】:

    猜你喜欢
    • 2017-03-30
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多