【问题标题】:Autofill SQL table field with Datetime value based on input parameter根据输入参数使用日期时间值自动填充 SQL 表字段
【发布时间】:2015-12-21 16:14:21
【问题描述】:

我的 SQL 表中有一个日期时间字段。我创建了一个将计数作为变量并为表生成记录的过程。如果计数为 5,它将生成 5 条记录。我想要的逻辑是,当我提供 5 作为输入参数时,表中的日期时间字段应自动填充值

12/20/2015 9:00
12/20/2015 11:00
12/20/2015 13:00
12/20/2015 15:00
12/20/2015 17:00

所以每次往表中插入一条记录,都要加上2个小时的时间。

【问题讨论】:

  • 我的错。我使用 MS SQL-Server
  • 您在任何时候要添加的记录数是否有上限和下限?你也有一些你尝试过的代码吗?
  • dateadd(h, 2, previousDate)
  • 是否总是从当前日期 9 点开始
  • 是的。这是一种自动预约程序。开始时间为第二天上午 9:00,根据输入参数,每条记录将增加 2 小时。最小值为 1,最大值为 6

标签: sql sql-server datetime stored-procedures dateadd


【解决方案1】:

递归CTEs 是动态创建记录的一种方法。这里的关键是创建一个锚点(这是 CTE 中的第一个 SELECT,这是您的起点)。和退出检查(这是 WHERE 子句)。

如果您想一次创建超过 100 条记录,请阅读 MAXRECURSION。

例子

DECLARE @RecordsRequired    INT = 5;
DECLARE @BaseDateTime        SMALLDATETIME = GETDATE();


WITH [Sample] AS
    (
        /* This CTE uses recursion to create the required number of 
         * records.
         */
            SELECT
                1                AS RowNumber,
                @BaseDateTime    AS [DateTime]

        UNION ALL

            SELECT
                RowNumber + 1                    AS RowNumber,
                DATEADD(HOUR, 2, [DateTime])    AS [DateTime]
            FROM
                [Sample]
            WHERE
                RowNumber < @RecordsRequired 
    )
SELECT
    RowNumber,
    [DateTime]
FROM
    [Sample]
;

您还可以查看WHILE 块。

【讨论】:

    【解决方案2】:

    使用此代码:

    ------------------ INPUT ------------------------
    declare @start_date datetime = '01/01/2000 14:00'
    declare @loops int = 5
    -------------------------------------------------
    
    declare @i int = 0
    while (@i < @loops) begin 
        select dateadd(hour, @i * 2, @start_date)
        set @i = @i + 1
    end
    

    【讨论】:

      【解决方案3】:

      在没有 LOOP

      的情况下试试这个
      Declare @count int = 5,
              @incrementer int =2 -- in case if you want to change the incrementer 
      
      SELECT Dateadd(hh, num * @incrementer, dates) 
      FROM   (SELECT Cast(CONVERT(VARCHAR(20), Dateadd(dd, 1, Getdate()), 111) 
                          + ' 9:00 AM' AS DATETIME) AS Dates, 
                     num 
              FROM   (VALUES(0),(1),(2),(3),(4),(5)) TC (num)) A 
      WHERE  num <= @count - 1 
      

      【讨论】:

        【解决方案4】:

        请在下面找到示例代码,它包含您需要的逻辑。希望对你有帮助!!

        --Create a temp table for sample output 
        CREATE TABLE #temp
        ( 
        CreatedDate datetime
        )
        
        --Declaring variables
        DECLARE @Count int
        DECLARE @TimeCounter int
        --intializing values
        SET @Count=5
        SET @TimeCounter=0
        
        
        WHILE(@Count>0)
        BEGIN
        --SELECT getdate()+1
        insert into #temp(#temp.CreatedDate) Select DATEADD(hour,@TimeCounter,getdate())
        SET @TimeCounter=@TimeCounter+2
        SET @Count=@Count-1
        END
        --Final values
        SELECT * FROM #temp tmp
        --Dropping table
        DROP TABLE #temp
        

        【讨论】:

          【解决方案5】:

          这是最好用数字表/函数解决的问题之一。与递归或循环相比,代码要少得多,通常对于任何重要且可重用的东西都更快。

          你要的核心代码是

          CREATE PROCEDURE usp_PopulateAppointments
          (
              @StartDateTime  datetime2(3),
              @Records        int,
              @Interval       int = 120       --Time between appointment slots in minutes. Default to 2h if not manually specified.
          )
          
          INSERT INTO Appointments
          SELECT
              DATEADD(m, @Interval * Number, @StartDateTime)
          FROM dbo.udfNumbers(0, @Recs)
          

          我在此假设了一个接受@StartAt 和@NumberResults 的数字函数。我在http://dataeducation.com/you-require-a-numbers-table/ 的 cmets 中使用了从 Adam 的最终代码派生的一个 - 根据我的经验,它比真正的桌子要快,而且占用的空间也更少。

          【讨论】:

            【解决方案6】:
            Create Table dates
                (
                datetimefield datetime not null
                )
                go
            
            Create Procedure FillDateTimeField
            @insertxrows  int
            AS
            begin
            Declare @LastDateTimeInserted as datetime
            set @LastDateTimeInserted  = (select isnull(max(datetimefield),getdate()) from Dates)
            ;WITH norows AS (
              SELECT 1 as num, Dateadd(hour,2,@LastDateTimeInserted) as FirstRecord
              UNION ALL
              SELECT num + 1, dateadd(hour,2,firstrecord) FROM 
              norows
               WHERE num < @insertxrows
            )
            insert into dates
            select firstrecord from norows
            end
            

            【讨论】:

              猜你喜欢
              • 2014-07-12
              • 1970-01-01
              • 2018-02-19
              • 1970-01-01
              • 2020-05-27
              • 1970-01-01
              • 2013-07-03
              • 2012-12-24
              • 2022-01-11
              相关资源
              最近更新 更多