【问题标题】:How to optimize a cycle in stored procedure [T-SQL]如何优化存储过程中的循环[T-SQL]
【发布时间】:2014-11-28 10:35:32
【问题描述】:

我在 T-SQL 中有这个存储过程,用于将 DATETIME 拆分为班次。

我会将DATETIME START 和DATETIME END 分成班次(例如,一班一小时或一班每15 分钟)。我应该把它转移到一个临时表中,以便在另一个查询中使用它。

为此我创建了这个循环:

BEGIN
      SET @DATASTART = '2014-11-28 06:00:00'
      SET @DATAEND = '2014-11-28 21:00:00'
    --DICHIARO DUE VARIABILI DATA CHE UTILIZZO
    --PER MANTENERE I DUE SHIFT
    DECLARE @DataFirstShift as DATETIME
    DECLARE @DataLastShift as DATETIME
    --DICHIARO UN CONTATORE PER POPOLARE IL CAMPO ID
    DECLARE @Contatore as INT
    SET @Contatore = 0
    --SETTO LA DATA FIRSTSHIFT A DATASTART
    SET @DataFirstShift = @DATA_START

    WHILE(@DataFirstShift <= @DATA_END)
        BEGIN
            --POPOLO LA DATA LAST CON UN ORA IN PIU RISPETTO ALLA PRIMA DATA
            IF @Shift LIKE 'All'
                BEGIN 
                    SET @DataLastShift = DATEADD(HOUR,1,@DataFirstShift)
                END
            ELSE 
                BEGIN 
                    SET @DataLastShift = DATEADD(MINUTE,15,@DataFirstShift)
                END
            INSERT INTO @TemporaryTable2 (ID,DATASTART,DATAEND)
            VALUES (@Contatore,@DataFirstShift,@DataLastShift)
            SET @DataFirstShift=@DataLastShift
            --INCREMENTO IL CONTATORE
            SET @Contatore+=1
        END
END

这种方法有效,但我这个周期很慢。我想知道是否存在比它更快的方法。

有人可以帮助我吗?问候

【问题讨论】:

标签: sql sql-server stored-procedures ssms


【解决方案1】:

试试下面:

--param of SP
DECLARE @DATASTART DATETIME = '2014-11-28 06:00:00'
DECLARE @DATAEND DATETIME = '2014-11-28 21:00:00'
DECLARE @Shift VARCHAR(50) = 'All'

--body
DECLARE @TemporaryTable2 TABLE
  (
     id        INT,
     startdate DATETIME,
     enddate   DATETIME
  )

DECLARE @id INT = 0

IF @Shift LIKE 'All'
BEGIN
    INSERT INTO @TemporaryTable2
    SELECT N.number + 1 AS id,
           startdate,
           enddate
    FROM   master..spt_values N
           CROSS apply (SELECT Dateadd(dd, N.number, @DATASTART),
                               Dateadd(dd, N.number + 1, @DATASTART)) AS D(startdate, enddate)
    WHERE  N.number BETWEEN 0 AND Datediff(dd, @DATASTART, @DATAEND)
           AND N.type = 'P'
END
ELSE
BEGIN
    INSERT INTO @TemporaryTable2
    SELECT N.number + 1 AS id,
           startdate,
           enddate
    FROM   master..spt_values N
           CROSS apply (SELECT Dateadd(MINUTE, N.number * 15, @DATASTART),
                               Dateadd(MINUTE, ( N.number + 1 ) * 15, @DATASTART)) AS D(startdate, enddate)
    WHERE  N.number BETWEEN 0 AND ( Datediff(MINUTE, @DATASTART, @DATAEND) / 15 )
           AND N.type = 'P'
END

SELECT *
FROM   @TemporaryTable2 

存在类似的问题here。此方法的唯一限制是spt_values 的范围是从 0 到 2047 的 type = 'p'。因此它最多可以返回 2047 行。

【讨论】:

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