2009-10-23 23 views
5

Đố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 ý" đó.

Trả lời

1

Bạn có thể thử SET CONTEXT_INFO từ trình kích hoạt để được đọc bởi CONTEXT_INFO() trong ứng dụng khách.

Chúng tôi sử dụng nó theo cách khác để chuyển thông tin vào trình kích hoạt nhưng sẽ hoạt động ngược lại.

+1

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 –

+0

@Rob: Tôi đã thêm câu trả lời cho điều này – gbn

1

Bạn trong trường hợp này đã thử @@ identity chưa? Bạn đã đề cập đến cả scope_Identity() và identity_current() nhưng không đề cập đến @@ identity.

+0

Tư duy tốt. Các "vấn đề" phạm vi thông thường có thể là một trợ giúp trong trường hợp này. – gbn

+0

Làm thế nào @@ IDENTITY sẽ tốt hơn IDENT_CURRENT()? Từ những gì tôi hiểu, trong khi không giới hạn phạm vi mã gọi, @@ IDENTITY là giá trị nhận dạng cuối cùng được chèn vào bất kể ở đâu. Vì vậy, nếu tôi có trình kích hoạt kiểm tra trên bảng chèn bản ghi vào bảng kiểm tra, @@ IDENTITY có thể trả về danh tính của hàng đó (nếu tôi hiểu chính xác). Đó là lý do tại sao tôi đã tìm ra IDENT_CURRENT() là tốt hơn vì nó ít nhất là giới hạn phạm vi "" đối với bảng cụ thể. – CuppM

+0

@CuppM: @@ IDENTITY là mỗi phiên, không phải trên mỗi phạm vi. IDENT_CURRENT() không phải là và có thể bởi bất kỳ phiên/phạm vi nào – gbn

Các vấn đề liên quan