SQL服务器 - 使用视图的INSTEAD OF触发器时获取插入的记录标识值(SQL Server

2019-08-31 19:20发布

对于具有标识字段几个表,我们使用的意见,而是对这些观点的触发器实现行级安全方案。 下面是一个简化的示例结构:

-- Table
CREATE TABLE tblItem (
    ItemId int identity(1,1) primary key,
    Name varchar(20)
)
go

-- View
CREATE VIEW vwItem 
AS
    SELECT *
    FROM tblItem
    -- RLS Filtering Condition
go

-- Instead Of Insert Trigger
CREATE TRIGGER IO_vwItem_Insert ON vwItem
INSTEAD OF INSERT
AS BEGIN
    -- RLS Security Checks on inserted Table

    -- Insert Records Into Table
    INSERT INTO tblItem (Name)
    SELECT Name
    FROM inserted;
END
go

如果我想插入一条记录,并得到其身份,执行RLS INSTEAD OF触发器之前,我使用:

DECLARE @ItemId int;

INSERT INTO tblItem (Name)
VALUES ('MyName');

SELECT @ItemId = SCOPE_IDENTITY();

随着扳机,SCOPE_IDENTITY()不再适用 - 它返回NULL。 我已经看到了使用OUTPUT子句,以获得身份回来的建议,但我似乎无法得到它的工作,我需要它的方式。 如果我把OUTPUT子句在视图上插入,没有什么是永远进到里面。

-- Nothing is added to @ItemIds
DECLARE @ItemIds TABLE (ItemId int);

INSERT INTO vwItem (Name)
OUTPUT INSERTED.ItemId INTO @ItemIds
VALUES ('MyName');

如果我把OUTPUT子句在INSERT语句中的触发,触发返回表(我可以从SQL Management Studio中查看)。 我似乎无法捕捉到它的调用代码; 或者通过使用在该呼叫的OUTPUT子句或使用SELECT * FROM()。

-- Modified Instead Of Insert Trigger w/ Output
CREATE TRIGGER IO_vwItem_Insert ON vwItem
INSTEAD OF INSERT
AS BEGIN
    -- RLS Security Checks on inserted Table

    -- Insert Records Into Table
    INSERT INTO tblItem (Name)
    OUTPUT INSERTED.ItemId
    SELECT Name
    FROM inserted;
END
go

-- Calling Code
INSERT INTO vwItem (Name)
VALUES ('MyName');

我能想到的唯一的事情就是使用IDENT_CURRENT()函数。 因为这并不在当前范围内运行,有并发用户同时插入和搞乱它的问题。 如果整个操作被包裹在一个交易,将防止并发问题?

BEGIN TRANSACTION

DECLARE @ItemId int;

INSERT INTO tblItem (Name)
VALUES ('MyName');

SELECT @ItemId = IDENT_CURRENT('tblItem');

COMMIT TRANSACTION

有没有人对如何做到这一点更好什么建议吗?

我知道人们在那里谁将会阅读本说“触发器是恶,不使用它们!” 虽然我很欣赏你的信念,请不要说提供“建议”。

Answer 1:

你可以试试SET CONTEXT_INFO从触发到被读取CONTEXT_INFO()的客户端。

我们使用它的其他方式的信息传递到触发,但在相反会工作。



Answer 2:

你有没有在这种情况下试图@@身份? 你提到的两个SCOPE_IDENTITY()和identity_current(),但不@@的身份。



文章来源: SQL Server - Get Inserted Record Identity Value when Using a View's Instead Of Trigger