【问题标题】:Bulk Insert the same row multiple (N) times批量插入同一行多次(N)次
【发布时间】:2020-04-20 03:23:19
【问题描述】:

有没有办法根据变量 N 将同一行 BULK 插入到表中?

基本上:

INSERT INTO Table (FK_id, Somedate)
VALUES (3, GETDATE())
OVER 5000 ROWS

我知道我可以声明 @InsertedRows 之类的变量并在 while 循环中递增:

DECLARE @InsertedRows = 0;
WHILE (@InsertedRows < N)
  INSERT INTO Table (FK_id, Somedate)
  VALUES (3, GETDATE())

  @InsertedRows++
END WHILE

但这是多个插入语句而不是 1 个插入调用,我更喜欢。有没有办法做到这一点?

【问题讨论】:

    标签: sql sql-server tsql azure-sql-database


    【解决方案1】:

    我发现递归 CTE 很容易从内存中完成,而且性能也很好。

    DECLARE @limit int = 5000;
    
    ;WITH x AS 
    (
        SELECT n = 1 UNION ALL 
        SELECT n + 1 FROM x WHERE n < @limit
    )
    INSERT dbo.tablename(FK_id, Somedate) 
    SELECT 3, GETDATE() FROM x
    OPTION (MAXRECURSION 0);
    

    【讨论】:

    • 整洁。我从不喜欢递归 CTE。我尽量在生产代码中避免使用它们,因为它们似乎总是在等待失败,但在这种情况下它是一个很好的用途。
    • @AaronBertrand 。 . .我同意。
    • @GordonLinoff:你同意哪一点?
    • @MitchWheat 。 . .投票支持递归 CTE。
    • 在生产代码中使用 (MAXRECURSION 0)?奇怪的选择。
    【解决方案2】:

    SSMS 中真正简单的方法是这样做:

    INSERT INTO Table (FK_id, Somedate)
    VALUES (3, GETDATE())
    GO 5000
    

    但它仍然是这样的多个插入。

    您可以像这样执行单个插入:

    WITH
        L0 AS (SELECT 1 AS c UNION ALL SELECT 1),
        L1 AS (SELECT 1 AS c FROM L0 A CROSS JOIN L0 B),
        L2 AS (SELECT 1 AS c FROM L1 A CROSS JOIN L1 B),
        L3 AS (SELECT 1 AS c FROM L2 A CROSS JOIN L2 B),
        L4 AS (SELECT 1 AS c FROM L3 A CROSS JOIN L3 B),
        L5 AS (SELECT 1 AS c FROM L4 A CROSS JOIN L4 B),
        Nums AS (SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS n FROM L5)
    INSERT INTO Table(FK_id, Somedate)
    SELECT TOP (5000) 
    FK_id, Somedate
    FROM Nums 
    CROSS APPLY (VALUES (3,  GETDATE())) t (FK_id, Somedate)
    ORDER BY n
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-21
      • 2022-08-17
      • 1970-01-01
      • 1970-01-01
      • 2013-09-10
      • 1970-01-01
      相关资源
      最近更新 更多