使用触发器中的OUTPUT输出插入记录的当前id

时间:2011-07-13 18:23:12

标签: sql-server-2008

我需要这样做:在插入的记录中,我需要存储已插入的项目标识和所选的项目标识。 (以下示例) 我在插入触发器之后使用(基本上我将一行从一个表复制到另一个表中并进行一些修改。 我有一个像这样的表参数:

DECLARE @Tempequipment TABLE
(Equipment_Id int,
DefaultEquipment_Id INT)

然后我插入这样的表:

INSERT INTO dbo.tblEquipmentType
        ( Name, EquipmentType_Id)  
SELECT name,(SELECT Equiment_Id FROM INSERTED)
FROM dbo.tblDefaultEquipmentType

这很好用!

我需要做的是:我需要插入刚刚复制的@TempEquipment EquipmentTypeId(可能不止一个)和刚刚复制的DefaultEquipmentTypeId。

我正在考虑做类似的事情:

INSERT INTO dbo.tblEquipmentType
            ( Name, EquipmentType_Id)  
Output EquipmentTypeId, DefaultEquipmentTypeId into @TempEquipment
    SELECT name,(SELECT Equipment_Id FROM INSERTED)
    FROM dbo.tblDefaultEquipmentType

但当然这不会起作用,因为它无法从select语句中获取值,也无法正确编写。 任何帮助表示赞赏!

更新
我有一个项目。物品可以建在不同的设备上。设备有类型(外键。而equipmentType有属性(foreignkey)。

所以这意味着我们有四个表Item-> Equipment-> EquipmentType-> EquipmentAttribute。 我需要为该类型存储默认的EquipmentTypes和默认的EquipmentAtrributes。

所以我也得到了这些重播:Equipment-> DefaultEquipmentType-> DefaultEquipmentAttribute。

现在,当我插入新项目并选择我想要将默认值复制到实际表格(EquipmentType,EquipmentAttribute)的设备时。 是否至少清楚了一点?

2 个答案:

答案 0 :(得分:0)

除了如何你正在尝试这样做(这是不行的),具体是什么你想要做什么?

这可能是通过更改/规范您的范例而不是某种奇特的代码来解决的。例如,拥有带有orderID字段的customers表看起来很奇怪。除非您的客户只订购一件事......我本来希望看到一个客户表,一个商品表,然后是一个订单表,用于加入客户的商品。

希望这是有道理的 - 但无论如何,如果没有,你可以张贴你的桌面结构,也许可以更清楚你提前知道什么(例如,我想你知道你的客户是谁,以及什么他们下令......在你插入之前......是吗?)

答案 1 :(得分:0)

对于INSERT语句,您只能访问插入列列表中的列,因此解决方案是将语句重写为MERGE语句,该语句可以访问所有列,包括例如INSERT目标表中的列IDENTITY列。

在演示中,我使用了dbo.INSERTED来模拟触发器中的INSERTED虚拟表。

USE master
GO
IF DB_ID('MergeOutputExample') IS NOT NULL
    DROP DATABASE MergeOutputExample
GO
CREATE DATABASE MergeOutputExample
GO
USE MergeOutputExample
GO
DECLARE @Tempequipment TABLE
(EquipmentId int,
DefaultEquipmentId INT,
ID int);

CREATE TABLE    dbo.INSERTED
(
    EquipmentTypeId         int PRIMARY KEY
);

CREATE TABLE    dbo.tblEquipmentType
(
    ID                      int         IDENTITY(1,1),
    Name                    varchar(50),
    EquipmentTypeId         int         PRIMARY KEY
);

CREATE TABLE    dbo.tblDefaultEquipmentType
(
    EquipmentTypeId         int,
    DefaultEquipmentTypeId  int         IDENTITY(1,1) PRIMARY KEY,
    Name                    varchar(50)
);

INSERT  dbo.inserted
        (
            EquipmentTypeId
        )
VALUES  (1);

INSERT  dbo.tblDefaultEquipmentType
        (
            EquipmentTypeId,
            Name
        )
VALUES  (
            1,
            'Hammer'
        );

MERGE   dbo.tblEquipmentType    AS ET
USING   (
            SELECT      DE.EquipmentTypeId,
                        DE.DefaultEquipmentTypeId,
                        DE.Name
            FROM        dbo.tblDefaultEquipmentType     DE
            INNER JOIN  dbo.INSERTED                    I
            ON          DE.EquipmentTypeId              = I.EquipmentTypeId 
        )                       AS DET
ON      ET.EquipmentTypeId          = DET.EquipmentTypeId
WHEN    NOT MATCHED BY TARGET
THEN    INSERT
        (
            Name,
            EquipmentTypeID
        )
        VALUES
        (
            DET.Name,
            DET.EquipmentTypeID
        )
OUTPUT  DET.EquipmentTypeId,
        DET.DefaultEquipmentTypeId,
        INSERTED.ID
INTO    @Tempequipment;

SELECT      *
FROM        @Tempequipment;

SELECT      *
FROM        dbo.tblEquipmentType;