如何使用光标一次插入1000个项目?

时间:2016-01-07 11:00:28

标签: sql sql-server tsql

现在我的sql查询在获取结束时一次插入所有行,但我想一次插入1000个项目,这样表格在插入时不会被锁定。

查询

Select status from table where 'condition' order by status desc

我怎样才能实现这一目标?

2 个答案:

答案 0 :(得分:0)

如果必须逐行进行,则需要声明并使用光标。这通常不是一个好主意,我很好奇为什么你需要这样做。你问题上的标签(fetch,while)意味着你已经对游标有了一些线索。一般形式看起来像:

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

- EDIT在下面的评论中添加了LOCAL STATIC 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 ...构造会更好。如果这是与课程相关的,则有一个家庭作业标签。我很难想到光标可以更好地服务于单个插入的情况。

答案 1 :(得分:0)

其他三种可能的选择:

  1. 使用可以首先检查冲突的MERGE语句 MATCHING子句,不匹配时只有INSERT
  2. IGNORE_DUP_KEY选项添加到索引中(通常不推荐, 取决于您的具体用例),以便碰撞插入 忽略。
  3. 预先计算可以安全插入的ID,然后在JOIN中使用它来选择它们并实际插入它们。
  4. 所有这些都将执行游标选项。

    如果你真的想要“一次1000个”,请在while循环中添加一个计数器,在它前面加BEGIN TRANSACTION,在它之后加COMMIT TRANSACTION,然后在其中:

    IF @counter % 1000 = 0 
    BEGIN
        COMMIT TRANSACTION
        BEGIN TRANSACTION
    END
    SET @counter = @counter + 1