[TSQL]在StoreProcedure裡寫for迴圈

  • 29360
  • 0
  • 2012-04-26

[TSQL]在StoreProcedure裡寫for迴圈

 

這真是讓人哭哭的要求QAQ
Leader要我改專案裡的某支程式把裡面的東西整個翻成StoreProcedure方便之後使用,
所以,這兩天都在翻這東西...Orz

過程當中就遇到了需要loop取資料再分別處理這樣的大問題,
查了很多,TSQL裡有WHILE可以使用可是不能針對已經選出來的資料集做FOREACH這類的動作
所以苦惱了好一陣,左翻翻右找找終於拼湊出了類似在TSQL裡寫FOR迴圈的寫法 Orz

以下看範例吧 ...  (使用北風資料庫...)


SELECT OrderID,CustomerID , Employees.FirstName + ' ' + Employees.LastName AS 'Employee'
FROM Orders INNER JOIN Employees ON Orders.EmployeeID =Employees.EmployeeID
WHERE  CustomerID IN ('ANATR')

跑出以下的資料集...

接下來針對以上的資料集結果作DEMO,


--宣告Table變數,使用#TempTable也是可以的
DECLARE @TempTable TABLE
(
	ID			INT ,  --ROW序號
	OrderID		VARCHAR(10),
	CustomerID	NVARCHAR(20),
	Employee	VARCHAR(30)
)
--把需要處理的資料集選出來丟到Table變數中
INSERT INTO @TempTable ( ID,OrderID,CustomerID,Employee)
	( SELECT ROW_NUMBER() OVER(ORDER BY OrderID) AS ID,,OrderID,CustomerID , Employees.FirstName + ' ' + Employees.LastName AS 'Employee'
		FROM Orders INNER JOIN Employees ON Orders.EmployeeID =Employees.EmployeeID
		WHERE  CustomerID IN ('ANATR')  )

--看一下現在@TempTable裡,已經塞好資料了		
SELECT * FROM  @TempTable  

DECLARE @TabelCount INT			 --loop的條件
	   ,@WhileTableCount INT = 1 
	   --
	   ,@Id      INT
	   ,@OrderId VARCHAR(10)
	   ,@Employee VARCHAR(30)
	   
SET @TabelCount = (SELECT COUNT(ID) FROM @TempTable)
--以下開始loop
WHILE @WhileTableCount <= @TabelCount
BEGIN
	
	--透過@WhileTableCount的定位取得每個row的值
	SELECT @Id = ID, @OrderId = OrderID, @Employee = Employee FROM @TempTable WHERE ID = @WhileTableCount
	
    ----Do Something Start----
	SELECT @Id AS 'ID' , @OrderId AS 'OrderId' , @Employee AS 'Employee'
	----Do Something End----
	
	--以下這句異常重要,忘記寫的話,SQL也是會跑無限迴圈的XD
	SET @WhileTableCount = @WhileTableCount + 1
END		

在這裡的示範,我使用的是Table變數來做loop處理,實際上使用#TempTable這種臨時的Table也是可以做的,
尤其是如果迴圈裡面又有迴圈的話第二個迴圈勢必要使用#TempTable (identiy會一直加下去,用#TempTable可以drop再create)

如果有前輩有更好的寫法,再請指教阿...Orz

2012/4/26 更新: 

根據Neil大的建議,把原來ID的欄位identity的部份去掉,改由ROW_NUMBER( )在選取時取得資料序號。
ROW_NUMBER( )使用方式-[SQL]為查詢的結果加上序號(ROW_NUMBER,RANK,OVER) FROM TOPCAT