首页 > 解决方案 > 批量创建具有外键依赖的行?

问题描述

我编写了一些用于更新单个客户的 SQL 语句。当此代码推出时,我必须更新所有客户。

现在客户 ID 是硬编码的,SQL 语句会根据该 ID 插入一条记录。原型工作,现在我想使用相同的算法为所有客户做 10,000 次插入。

DECLARE @customerID BIGINT = 47636;
DECLARE @limitFourAdjustment MONEY;
DECLARE @appliesToDateTime DATETIME2(7) = SYSUTCDATETIME();

DECLARE @dp_y INT = DATEPART(YEAR, @appliesToDateTime);
DECLARE @dp_m INT = DATEPART(MONTH, @appliesToDateTime);
DECLARE @dp_w INT = DATEPART(WEEK, @appliesToDateTime);
DECLARE @dp_d INT = DATEPART(DAY, @appliesToDateTime);
DECLARE @dp_h INT = DATEPART(HOUR, @appliesToDateTime);
DECLARE @d_h DATETIME2(7) = DATEADD(HOUR, DATEDIFF(HOUR, 0, @appliesToDateTime), 0);

SELECT
    @limitFourAdjustment = -COALESCE(SUM(COALESCE(Amount, 0)), 0)
FROM 
    [dbo].Transactions
WHERE
    CustomerID = @customerID AND
    IsSystemVoid = 0 AND
    TransactionTypeID IN (SELECT ID FROM TransactionTypes WHERE TransactionTypeGroupID = 3)

INSERT INTO dbo.CustomerAccounts_TransactionSummation (CustomerID, LimitTypeID, Y, M, W, D, H, YMDH, Amount)
VALUES (@customerID, 4, @dp_y, @dp_m, @dp_w, @dp_d, @dp_h, @d_h, @limitFourAdjustment);

我尝试添加一个while循环,似乎不是最快的解决方案。也许先收集 ID,然后通过循环将其输入?我在下面的第一次尝试不起作用,因为我只是得到最后一个客户 ID,而不是每次都是唯一的。

SELECT @numberOfCustomers = COUNT(*) 
FROM  dbo.Customers

WHILE(@numberOfCustomers > 0)
BEGIN
    SELECT @customerID = ID FROM dbo.Customers

    OTHER LOGIC FROM ABOVE

    SET @numberOfCustomers = @numberOfCustomers - 1;
END

那么问题来了,如何在每个客户的 ID 上运行这些 SQL 语句(第一个代码块)?

标签: sql-servertsql

解决方案


使用数据库的关键是让您考虑基于集合的操作,而不是过程操作。数据库旨在一次自然地对一组数据进行操作,但是您必须将您对问题的看法更改为您处理整个数据集而不是一次处理一条记录的方式。

所以这里是我认为可以一次性完成完整更新的 SQL:

INSERT INTO dbo.CustomerAccounts_TransactionSummation (CustomerID, LimitTypeID, Y, M, W, D, H, YMDH, Amount)
  SELECT
    id
    , 4 
    , @dp_y
    , @dp_m
    , @dp_w
    , @dp_d
    , @dp_h
    , @d_h
    , -COALESCE(SUM(COALESCE(Amount, 0)), 0) limitFourAdjustment
  FROM [dbo].Transactions
  WHERE IsSystemVoid = 0
  and TransactionTypeID IN (SELECT ID FROM TransactionTypes WHERE TransactionTypeGroupID = 3)
  --and CustomerID = @customerID

请注意,insert可以直接与 a 组合select,而不是使用values


推荐阅读