2016-01-07 47 views
1

現在我的sql查詢一次插入所有的行,但是我想一次插入1000個項目,這樣插入過程中表格就不會被鎖定。如何使用光標一次插入1000個項目?

查詢

DECLARE cur CURSOR FOR SELECT Some variables FROM @CardNumbers 
     OPEN cur 


begin tran 
      FETCH NEXT FROM cur INTO Some variables 

         WHILE @@FETCH_STATUS = 0 BEGIN 
          BEGIN TRY 
           select @id = @@CURSOR_ROWS 
           //INSERT 
          END TRY 
          BEGIN CATCH 
             if (ERROR_NUMBER() = 2601) 
              begin 
               set @DuplicateCardNo = @DuplicateCardNo + 1 
              end 
             else 
              throw 
          END CATCH 

          FETCH NEXT FROM cur INTO Some variables 
         END 
      commit tran 


     CLOSE cur  
     DEALLOCATE cur 

我怎樣才能做到這一點?

+0

不這樣做然後用光標 - >插入mytable(col1,col2,col3)從myOtherTableOr中選擇val1,val2,val3任何 – gsharp

+0

我需要進行檢查之前我可以插入table1中的每一行,然後我可以將數據插入到table2中 – Timsen

+1

您可以插入從光標到#temp表格,然後快速插入並插入/選擇到最終目的地。然而,大多數東西可以在我的經驗中無需光標就可以完成。 – gsharp

回答

0

如果您必須逐行進行,您將聲明並使用遊標。這通常不是一個好主意,我會好奇你爲什麼需要這樣做。你問題上的標籤(取,while)意味着你已經對遊標有了一些線索。一般形式看起來類似:

SET NOCOUNT ON; 
DECLARE @num INT; -- other columns 

- 編輯添加本地靜態READ_ONLY FORWARD_ONLY根據註釋下面

DECLARE excruciatingly_slow CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY FOR 
    SELECT 1 --this is just a sample, your query (which you might want to supply) will differ 
    UNION ALL 
    SELECT 2; 

OPEN excruciatingly_slow;  
FETCH NEXT FROM excruciatingly_slow 
    INTO @num -- other variables 
    ; 

WHILE @@FETCH_STATUS > -1 
    BEGIN 
     -- Do something here 
     INSERT destination_table 
      ( column_list -- other columns... 
      ) 
     SELECT @num -- other columns 
      ; 

     FETCH NEXT FROM excruciatingly_slow 
      INTO @num-- other variables 
      ; 
    END; 
CLOSE excruciatingly_slow; 
DEALLOCATE excruciatingly_slow; 

在大多數情況下,這將與INSERT可以做得更好... SELECT ...其他答覆建議的構念。如果這與課程相關,則有一個作業標籤。我很難考慮一個遊標可以更好地提供單個插入的情況。其他

+0

我同意這是一個非常緩慢的方法,但問題是我需要使在我可以將同一行插入到表格2之前對table1中的每一行進行重複檢查 – Timsen

+0

您不能使用[GROUP BY](https://msdn.microsoft.com/en-us/library/ms177673.aspx)刪除重複項代替?這將允許您切換到基於集合的查詢,這是SQL真正的優勢所在。 –

0

三種可能的選擇:

  1. 使用MERGE語句可以檢查衝突首先使用 的MATCHING條款,只有INSERT時不匹配。
  2. IGNORE_DUP_KEY選項添加到索引(通常不推薦, 取決於您的具體使用情況),以便碰撞插入將被忽略 。
  3. 預先計算可安全插入的ID,然後在JOIN中使用該ID選擇它們並實際插入它們。

所有這些將執行光標選項。

如果你真的想,while循環添加一個計數器,一個BEGIN TRANSACTION前,後一個COMMIT TRANSACTION,並且,其中的「在時間1000」:

IF @counter % 1000 = 0 
BEGIN 
    COMMIT TRANSACTION 
    BEGIN TRANSACTION 
END 
SET @counter = @counter + 1 
相關問題