2014-12-22 68 views
0

我想在SQL Server 2012中使用公用表表達式(CTE)而不是光標。非常感謝您的幫助。如何使用CTE而不是光標

這是我的情況:

DECLARE 
@tp_ID INTEGER 

truncate table T_Rep_Exit_Checklist_Table 

DECLARE cursorName CURSOR -- Declare cursor 
LOCAL SCROLL STATIC 

FOR 

SELECT 
tp_ID 
from V_Rep_Exit_Checklist 

OPEN cursorName -- open the cursor 

FETCH NEXT FROM cursorName INTO @tp_ID 

WHILE @@FETCH_STATUS = 0 

BEGIN 

insert into T_Rep_Exit_Checklist_Table 
SELECT 
@tp_ID-- AS tp_ID 
,Item_Status_Code 
,Item_Status_Desc 
,Item_Code 
,Item_Desc 
,Item_Cat_Code 
,Item_Cat_Desc 
,Item_Cleared_By_No 
,Item_Cleared_By_Name 
V_Rep_Exit_Checklist c 


    FETCH NEXT FROM cursorName 
    INTO @tp_ID 
END 

CLOSE cursorName -- close the cursor 

DEALLOCATE cursorName -- Deallocate the cursor 

回答

0

一些關於您的查詢似乎沒有什麼意義。看起來你的INSERT語句在SELECT中缺少一個where子句,因此如果你的源視圖有5個記錄作爲實例,你插入了25條記錄,因爲你在第一次迭代期間用光標取第一個記錄的id,並且插入全部用該ID記錄,然後對視圖的每一行重複。

假設上述邏輯打算,那麼你應該只需要一個CROSS JOIN:

INSERT T_Rep_Exit_Checklist_Table 
    SELECT 
     T1.tp_ID, 
     T2.Item_Status_Code, 
     T2.Item_Status_Desc, 
     T2.Item_Code, 
     T2.Item_Desc, 
     T2.Item_Cat_Code, 
     T2.Item_Cat_Desc, 
     T2.Item_Cleared_By_No, 
     T2.Item_Cleared_By_Name 
    FROM V_Rep_Exit_Checklist T1 
     CROSS JOIN V_Rep_Exit_Checklist T2 

但是,你想看到它的CTE:

;WITH CTE AS (
    SELECT * FROM V_Rep_Exit_Checklist 
) 
INSERT T_Rep_Exit_Checklist_Table 
    SELECT 
     T1.tp_ID, 
     T2.Item_Status_Code, 
     T2.Item_Status_Desc, 
     T2.Item_Code, 
     T2.Item_Desc, 
     T2.Item_Cat_Code, 
     T2.Item_Cat_Desc, 
     T2.Item_Cleared_By_No, 
     T2.Item_Cleared_By_Name 
    FROM CTE T1 
     CROSS JOIN CTE T2 

如果我的假設是錯誤的而是嘗試將視圖中的所有記錄直接插入到表中,那麼爲什麼不僅僅是一個簡單的INSERT?

INSERT T_Rep_Exit_Checklist_Table 
    SELECT 
     tp_ID, 
     Item_Status_Code, 
     Item_Status_Desc, 
     Item_Code, 
     Item_Desc, 
     Item_Cat_Code, 
     Item_Cat_Desc, 
     Item_Cleared_By_No, 
     Item_Cleared_By_Name 
    FROM V_Rep_Exit_Checklist 

但是,如果你的業務需求是這樣的:你只能一次插入從您的視圖1 TP_ID記錄,while語句可以用來替換光標:

DECLARE @Records TABLE (tp_ID INT) 
INSERT @Records 
    SELECT tp_ID FROM V_Rep_Exit_Checklist 
DECLARE @tp_ID INTEGER 
WHILE EXISTS (SELECT * FROM @Records) BEGIN 
    SET @tp_ID = (SELECT TOP 1 tp_ID FROM @Records) 
    INSERT T_Rep_Exit_Checklist_Table 
     SELECT 
      tp_ID, 
      Item_Status_Code, 
      Item_Status_Desc, 
      Item_Code, 
      Item_Desc, 
      Item_Cat_Code, 
      Item_Cat_Desc, 
      Item_Cleared_By_No, 
      Item_Cleared_By_Name 
     FROM V_Rep_Exit_Checklist 
     WHERE tp_ID = @tp_ID 
    DELETE @Records WHERE tp_ID = @tp_ID 
END