【问题标题】:How does one use loops in TSQL?如何在 SQL 中使用循环?
【发布时间】:2013-03-24 03:39:30
【问题描述】:

在 TSQL 中,我想将以下代码从必须使用硬编码的 dhome 更改为使用循环进行优化。我尝试添加循环失败的尝试也包括在内。

Declare  @dhome Tinyint, @bp smallint, @lr smallint, @q smallint

    // Set @dhome = 1
  While(@dhome <= 3) // My attempt to add a loop

  SELECT @lr = MAX(NQdDate), @q = NQd
  FROM NQdHistory
  WHERE dhomeId = @dhome 
  GROUP BY NQdDate, NQd

  SELECT @bd = COUNT(*)
  FROM bdhome
  WHERE NQdDate= @lr AND dhomeID= @dhome 

  DELETE FROM ND1 WITH(XLOCK)
  WHERE dhomeID= @dhome  AND NQdDate= @lr

  UPDATE NQdHistory
  SET Nbd = @q - @@RowCount - @bp, NBd = @bp
  WHERE NQdDate= @lr AND dhomeID= @dhome 

  Set @dhome = @dhome +1 //My attempt to end a loop

【问题讨论】:

  • 你需要一个 BEGIN 和 END 在你的 while 下

标签: tsql loops for-loop while-loop


【解决方案1】:

你在正确的轨道上。你错过了开始和结束。另外,一定要给@dhome 一个值。看起来你已经开始并在你的第三行注释掉了:

Declare  @dhome Tinyint, @bp smallint, @lr smallint, @q smallint

    // Set @dhome = 1
While(@dhome <= 3) // My attempt to add a loop
begin
  SELECT @lr = MAX(NQdDate), @q = NQd
  FROM NQdHistory
  WHERE dhomeId = @dhome 
  GROUP BY NQdDate, NQd

  SELECT @bd = COUNT(*)
  FROM bdhome
  WHERE NQdDate= @lr AND dhomeID= @dhome 

  DELETE FROM ND1 WITH(XLOCK)
  WHERE dhomeID= @dhome  AND NQdDate= @lr

  UPDATE NQdHistory
  SET Nbd = @q - @@RowCount - @bp, NBd = @bp
  WHERE NQdDate= @lr AND dhomeID= @dhome 

  Set @dhome = @dhome +1 //My attempt to end a loop
end  

如果您熟悉 C/C#/C++,如果您更熟悉 VB ThenEnd If,请将 T-SQL 的 Begin 和 End 想象成花括号 {}。或者更像是帕斯卡 BeginEnd。你明白了:)

【讨论】:

  • 如果我在 TSQL 中做一个 for 循环会不会是同样的方式?
  • 在 T-SQL 中并没有真正意义上的 FOR 循环。然而,答案中的代码基本上模拟了FOR 循环的功能。
  • 感谢亚当的帮助!
【解决方案2】:

在你的时间里错过了开始和结束。

WHILE (Transact-SQL)

【讨论】:

    【解决方案3】:

    示例 1

    DECLARE @I INT,@COUNTVAR INT
    SET @I = 1
    DECLARE @Parent_Child TABLE(ID INT IDENTITY(1,1),ParentPositionID INT NULL,ChildPositionId Int)
    
    INSERT INTO @Parent_Child(ParentPositionID,ChildPositionId) 
    SELECT DISTINCT PARENT_POSITION_ID,CHILD_POSITION_ID from tblPOSITION_HIERARCHY 
    --WHERE CHILD_POSITION_ID IN (--YOUR CONDITION IF ANY)
    SELECT @COUNTVAR =COUNT(*) FROM @PTS_Parent_Child
    DECLARE @int_SUPE_POSITION_ID INT, @int_CHILD_POSITION_ID INT
     --loop through records here 
    WHILE @I <= @COUNTVAR
    BEGIN
    SELECT @int_SUPE_POSITION_ID=ParentPositionID,@int_CHILD_POSITION_ID=ChildPositionId  FROM @Parent_Child WHERE ID=@I   
    --Whatever you want to do with records
    SET @I=@I+1
    END
    

    示例 2

    如果您可以使用临时表,这只是另一种方法。我已经亲自测试过,它不会导致任何异常(即使临时表没有任何数据。)

    CREATE TABLE #TempTable
        (
          ROWID int identity(1,1) primary key,
          HIERARCHY_ID_TO_UPDATE int,
        )
        --INSERT DATA INTO TEMP TABLE USING INSERT INTO CLAUSE OR FOR EAXMPLE BELOW
        --INSERT INTO #TempTable VALUES(1)
        --INSERT INTO #TempTable VALUES(2)
        --INSERT INTO #TempTable VALUES(4)
        --INSERT INTO #TempTable VALUES(6)
        --INSERT INTO ##TempTable VALUES(8)
    
    
        DECLARE @MAXID INT
        SET @COUNTER =1
        SELECT @MAXID=COUNT(*) FROM #TempTable
        --PRINT @MAXID
        WHILE (@MAXID > 0)
        BEGIN
             --DO THE PROCESSING HERE 
             SELECT @HIERARCHY_ID_TO_UPDATE =PT.HIERARCHY_ID_TO_UPDATE FROM      #TempTable  PT WHERE ROWID=@COUNTER
             --PRINT '@MAXID VALUE '
             --PRINT  @MAXID
            SET @MAXID=@MAXID-1
            SET @COUNTER =@COUNTER + 1
        End
    
    
        If(OBJECT_ID('tempdb..#TempTable') IS NOT NULL)
        BEGIN
            DROP TABLE #TempTable
        END
    

    【讨论】:

      猜你喜欢
      • 2013-08-18
      • 2018-11-29
      • 2012-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-16
      • 2020-02-08
      • 2020-07-09
      相关资源
      最近更新 更多