Đối với một số bảng có trường nhận dạng, chúng tôi đang thực hiện lược đồ Bảo mật cấp độ hàng bằng cách sử dụng Chế độ xem và Thay vì kích hoạt trên các chế độ xem đó. Dưới đây là một ví dụ đơn giản cấu trúc:Máy chủ SQL - Nhận giá trị bản ghi được chèn khi sử dụng chế độ xem thay vì kích hoạt
-- 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
Nếu tôi muốn chèn một bản ghi và nhận được bản sắc của mình, trước khi thực hiện RLS Thay vào đó Of cò, tôi đã sử dụng:
DECLARE @ItemId int;
INSERT INTO tblItem (Name)
VALUES ('MyName');
SELECT @ItemId = SCOPE_IDENTITY();
Với cò, SCOPE_IDENTITY () không còn hoạt động nữa - nó trả về NULL. Tôi đã nhìn thấy các đề xuất cho việc sử dụng mệnh đề OUTPUT để lấy lại danh tính, nhưng tôi dường như không thể làm cho nó hoạt động theo cách tôi cần. Nếu tôi đặt mệnh đề OUTPUT trên khung nhìn chèn, thì không có gì được nhập vào nó.
-- Nothing is added to @ItemIds
DECLARE @ItemIds TABLE (ItemId int);
INSERT INTO vwItem (Name)
OUTPUT INSERTED.ItemId INTO @ItemIds
VALUES ('MyName');
Nếu tôi đặt mệnh đề OUTPUT trong trình kích hoạt trên câu lệnh INSERT, trình kích hoạt sẽ trả về bảng (tôi có thể xem nó từ SQL Management Studio). Tôi dường như không thể nắm bắt nó trong mã gọi; hoặc bằng cách sử dụng mệnh đề OUTPUT trên cuộc gọi đó hoặc sử dụng 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');
Điều duy nhất tôi có thể nghĩ là sử dụng hàm IDENT_CURRENT(). Vì nó không hoạt động trong phạm vi hiện tại, có một vấn đề của người dùng đồng thời chèn cùng một lúc và làm rối tung nó lên. Nếu toàn bộ hoạt động được gói trong một giao dịch, điều đó có ngăn được vấn đề tương tranh không?
BEGIN TRANSACTION
DECLARE @ItemId int;
INSERT INTO tblItem (Name)
VALUES ('MyName');
SELECT @ItemId = IDENT_CURRENT('tblItem');
COMMIT TRANSACTION
Có ai có bất kỳ đề xuất nào về cách thực hiện điều này tốt hơn không?
Tôi biết mọi người ở đó, những người sẽ đọc nội dung này và nói "Trình kích hoạt là EVIL, đừng sử dụng chúng!" Trong khi tôi đánh giá cao niềm tin của bạn, xin vui lòng không cung cấp "gợi ý" đó.
Xem câu hỏi liên quan của tôi về CONTEXT_INFO() sử dụng: http://stackoverflow.com/questions/1616229/contextinfo-and-convert –
@Rob: Tôi đã thêm câu trả lời cho điều này – gbn