web-dev-qa-db-ja.com

SQLでループをどのように使用しますか?

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
9
user1880670

あなたは正しい方向に進んでいます。あなたはあなたの始まりと終わりを逃しています。また、必ず@dhomeに値を付けてください。あなたが始めて、3行目にコメントアウトしたようです:

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++に精通している場合は、T-SQLの開始と終了を中括弧{}のように考えてください。VBThenに精通している場合はおよびEnd If。または、パスカルBeginEndのように。あなたはアイデアを得る:)

15
Adam Plocher

例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
2
Sandeep

あなたの間に始まりと終わりを逃している。

WHILE(Transact-SQL)

2
Jason Carter