【问题标题】:SQL: Can't insert a date loop into a columnSQL:无法将日期循环插入列
【发布时间】:2015-10-13 09:31:11
【问题描述】:

我有一张这样的桌子:

id: PK bigint
RatePercent: decimal(4, 4)
DateRange: date

我正在尝试按如下方式填充表格:

  • RatePercentage 全部为 0.12
  • 日期从 '01-01-2015' 到 '12-31-2099'

不幸的是,我的查询不会那样做,并且一直说

操作数类型冲突:日期与 int 不兼容

除了 id bigint 之外,我还没有分配 int 数据类型。我有点困惑。

这是我目前的查询:

DECLARE @Date Date
SET @Date = '01-01-2015'

WHILE @Date <= '12-31-2099'
BEGIN
    INSERT INTO [dbo].[IMF_Main_VATHistory] (VATRate, VATDate)
    VALUES (0.12, @Date + 1);
END

【问题讨论】:

    标签: sql-server


    【解决方案1】:

    试试这个:

    DECLARE @Date Date
    SET @Date = '01-01-2015'
    
    WHILE @Date <= '12-31-2099'
    BEGIN
        INSERT INTO [dbo].[IMF_Main_VATHistory] (VATRate, VATDate)
        VALUES (0.12, DATEADD(DAY, 1, @Date));
    
        SET @Date = DATEADD(DAY, 1, @Date);
    END
    

    您不能在 SQL Server 中直接添加到 DATE 数据类型(作为参考,我认为您可以在 Oracle 中)。您必须使用函数来修改 DATE/DATETIME 变量(或列)。

    这是一个例子SQLFiddle

    【讨论】:

      【解决方案2】:

      我认为问题在于“@Date + 1” - SQL-Server 喜欢尝试转换为 INT :)

      使用应该可以工作的DATEADD

      DECLARE @Date Date
      SET @Date = '01-01-2015'
      
      WHILE @Date <= '12-31-2099'
      BEGIN
          INSERT INTO [dbo].[IMF_Main_VATHistory] (VATRate, VATDate)
          VALUES (0.12, @Date);
          SET @Date = DATEADD(DAY, 1, @Date);
      END
      

      【讨论】:

      • 您的解决方案不会给出正确答案。您正在插入 31046 个相同的日期。我不喜欢在 sql 中循环。它几乎总是可以避免的。
      • 是的 - 我同意,但问题是如何修复“操作数类型冲突:日期与 int 不兼容”,因此没有使用时间进行优化,只是问题的答案。
      【解决方案3】:

      我建议不要使用任何基于循环或 RBAR 的解决方案。您可以在Tally Table 的帮助下使用基于集合的方法来执行此操作。

      DECLARE @startDate DATE
      DECLARE @endDate DATE
      
      SET @startDate  = '20150101'
      SET @endDate = '20991231';
      
      
      WITH E1(N) AS(
          SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
          SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
      ),
      E2(N) AS(SELECT 1 FROM E1 a, E1 b),
      E4(N) AS(SELECT 1 FROM E2 a, E2 b),
      E8(N) AS(SELECT 1 FROM E4 a, E4 b),
      Tally(n) AS(
          SELECT TOP(DATEDIFF(DAY, @startDate, @endDate) + 1)
              ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
          FROM E8
      )
      INSERT INTO IMF_Main_VATHistory(RatePercent, DateRange)
      SELECT 
          0.02, DATEADD(DAY, N-1, @startDate)
      FROM Tally
      

      与使用 CURSORs 或 WHILE 循环相比,它更快。

      【讨论】:

      • 那么,我需要为这个过程创建一个临时表(tally)吗?
      • 不需要,您可以即时创建。级联 CTE 会为您做到这一点。
      • 好吧。顺便说一句,我也是Pinoy。 =)
      • 嗯,循环失败了,只重复了 2015-01-02。所以我停止了它。我现在正在尝试你的程序。如果这可行,那么您将获得最佳答案的啤酒(啤酒,如果您在附近)
      • @JoshuaMasangcay 循环失败,内存不足,因为变量的值没有任何实际增量,所以那里有一个无限循环。只是对性能感到好奇,现在再次运行脚本。
      猜你喜欢
      • 1970-01-01
      • 2011-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-18
      • 2011-12-20
      • 2014-03-11
      相关资源
      最近更新 更多