如何插入从上一个表自动增量ID中选择

Rez*_*dar 0 sql sql-server

我有两个表,如下所示:

在此输入图像描述

我需要通过存储过程插入一些数据,如下代码:

ALTER PROCEDURE [dbo].[DeviceInvoiceInsert]
    @dt AS DeviceInvoiceArray READONLY
AS
    DECLARE @customerDeviceId BIGINT
    DECLARE @customerId BIGINT
    DECLARE @filterChangeDate DATE
BEGIN
    SET @customerId = (SELECT TOP 1 CustomerId FROM @dt 
                       WHERE CustomerId IS NOT NULL)
    SET @filterChangeDate = (SELECT TOP 1 filterChangeDate FROM @dt)

    INSERT INTO CustomerDevice (customerId, deviceId, deviceBuyDate, devicePrice)
        SELECT customerId, deviceId, deviceBuyDate, devicePrice 
        FROM @dt 
        WHERE CustomerId IS NOT NULL

    SET @customerDeviceId = SCOPE_IDENTITY()

    INSERT INTO FilterChange (customerId, filterId, customerDeviceId, filterChangeDate)
        SELECT @customerId, dt.filterId, @customerDeviceId, @filterChangeDate 
        FROM @dt AS dt
END
Run Code Online (Sandbox Code Playgroud)

问题在于,当过程想要将数据插入表中时FilterChange@customerDeviceId总是具有最后一个 IDENTITY Id。

我怎样才能解决这个问题?

更新 感谢您的@T N回答,但他的解决方案只是为每个设备插入一个过滤器,所以就我而言,每个设备可以有多个过滤器

T N*_*T N 5

如上所述,使用OUTPUT子句是捕获插入的 IDENTITY 或其他隐式分配值的最佳方法。但是,您还需要将此数据与源表中的其他值关联起来。据我所知,使用常规语句无法做到这一点,常规语句只能通过伪表INSERT从目标表中捕获数据。INSERTED

我假设第一个目标表中显式插入的值都不能用于可靠地唯一标识源记录。

解决方法是使用该MERGE语句执行插入。然后该OUTPUT子句可用于捕获源数据和插入的目标数据的组合。

ALTER PROCEDURE [dbo].[DeviceInvoiceInsert]
    @dt AS DeviceInvoiceArray READONLY
AS
BEGIN
    -- Temp table to receive captured data from output clause
    DECLARE @FilterChangeData TABLE (
        customerId INT,
        filterId INT,
        customerDeviceId INT,
        filterChangeDate DATETIME2
    )

    -- Merge is used instead of a plain INSERT so that we can capture
    -- a combination of source and inserted data
    MERGE CustomerDevice AS TGT
    USING (SELECT * FROM @dt WHERE CustomerId IS NOT NULL) AS SRC
        ON 1 = 0 -- Never match
    WHEN NOT MATCHED THEN
        INSERT (customerId, deviceId, deviceBuyDate, devicePrice)
        VALUES (SRC.customerId, SRC.deviceId, SRC.deviceBuyDate, SRC.devicePrice) 
        OUTPUT SRC.customerId, SRC.filterId, INSERTED.customerDeviceId, SRC.filterChangeDate
            INTO @FilterChangeData
    ;

    INSERT INTO FilterChange (customerId, filterId, customerDeviceId, filterChangeDate)
        SELECT customerId, filterId, customerDeviceId, filterChangeDate 
        FROM @FilterChangeData
END
Run Code Online (Sandbox Code Playgroud)

给定以下@dt源数据:

客户ID 设备ID 设备购买日期 设备价格 过滤器ID 过滤器更改日期
11 111 2023-01-01 111.1100 1111 2023-02-01
22 222 2023-01-02 222.2200 2222 2023-02-02
33 第333章 2023-01-03 333.3300 3333 2023-02-03
11 222 2023-01-04 333.3300 1111 2023-02-04

以下内容被插入到 CustomerDevice 中:

客户设备ID 客户ID 设备ID 设备购买日期 设备价格
1 11 111 2023-01-01 111.1100
2 22 222 2023-01-02 222.2200
3 33 第333章 2023-01-03 333.3300
4 11 222 2023-01-04 333.3300

以下内容被插入到 FilterChange 中:

客户ID 过滤器ID 客户设备ID 过滤器更改日期
11 1111 1 2023-02-01
22 2222 2 2023-02-02
33 3333 3 2023-02-03
11 1111 4 2023-02-04

请参阅此 db<>fiddle