Sql-Server

我可以通過數據庫觸發器獲取 SQL Server 擷取更新以反映負責的 objectid 嗎?

  • August 18, 2016

我有一個執行多個儲存過程並將結果行儲存在目標表中的表[TestTable]

[TestTable]首先由儲存過程填充[spInsertRowToTestTable],然後由[spUpdatesRowInTestTableFirst]和更新[spUpdatesRowInTestTableLast]

我可以通過使用預設約束來設置表中初始插入的負責過程來設置@@PROCID. 我想以類似的方式擷取更新,而不修改導致行更新的現有過程。

我已經嘗試過,但我無法創建擷取任何後續更新的觸發器或類似解決方案。呼叫過程的範圍使我嘗試在觸發器中擷取它並更新行。

有沒有直接的方法來做到這一點?

請參見下面的範常式式碼:

--DROP SCHEMA test;
--GO
--DROP TABLE test.TestTable;
CREATE SCHEMA test;
GO

CREATE TABLE test.TestTable
   (
     Column1 NVARCHAR(20) NULL ,
     RowInsertedBySP NVARCHAR(30)
       NULL
       CONSTRAINT DF_TestTable_RowInsertedBySP DEFAULT OBJECT_NAME(@@PROCID) ,
     RowUpdatedBY NVARCHAR(20)
   );
GO

CREATE PROCEDURE test.spInsertRowToTestTable
AS
   INSERT  INTO test.TestTable
           ( Column1 )
   VALUES  ( 'TestRow' );
GO

CREATE PROCEDURE test.spUpdatesRowInTestTableFirst
AS
   UPDATE test.TestTable
   SET Column1 = 'Updated ' +[Column1]; 
GO

EXEC test.spInsertRowToTestTable;

SELECT  *
FROM    test.TestTable AS tt;

導致:

Column1              RowInsertedBySP                RowUpdatedBY
-------------------- ------------------------------ --------------------
TestRow              spInsertRowToTestTable         NULL

(1 row(s) affected)

我只想擷取對 column 中的行執行更新的過程的 ID [RowUpdatedBy]

即如果我有[spUpdatesRowInTestTableFirst][spUpdatesRowInTestTableLast]。然後該列[RowUpdatedBy]應反映如下更新:

Column1              RowInsertedBySP                RowUpdatedBY
-------------------- ------------------------------ --------------------
TestRow              spInsertRowToTestTable        spUpdatesRowInTestTableFirst, spUpdatesRowInTestTableLast    

我看過一個使用 DBCC Outputbuffer 的例子,但我不想走那條路。我們使用企業版,所以另一個想法是利用 CDC。

我會很感激任何意見。

如果你想知道誰在什麼時候寫了什麼,我會創建 2 個使用者,一個用於每個涉及的程序,然後 創建以使用者身份執行的程序

在您的測試表上添加一個額外的列以保留 session_user 或 current_user,以便您知道誰插入/更新了每條記錄,因為 insert_procedure 將作為 insert_user 執行,而 update_procedure 將作為 update_user 執行。

此腳本可以幫助您找出原始登錄名,並比較不同的使用者定址方式。

DECLARE @User VARCHAR(20)
SELECT @USER = SUBSTRING(SUSER_SNAME(), 
              CHARINDEX('\', 
              SUSER_SNAME()) + 1, 
              LEN(SUSER_SNAME()))


SELECT   @USER 
       , SUSER_SNAME()
       ,SYSTEM_USER
       , USER_NAME()
       , CURRENT_USER
       , ORIGINAL_LOGIN()
       ,USER
       ,SESSION_USER


EXECUTE AS LOGIN='my_user'

--DECLARE @User VARCHAR(20)
SELECT @USER = SUBSTRING(SUSER_SNAME(), 
              CHARINDEX('\', 
              SUSER_SNAME()) + 1, 
              LEN(SUSER_SNAME()))


SELECT   @USER 
       , SUSER_SNAME()
       ,SYSTEM_USER
       , USER_NAME()
       , CURRENT_USER
       , ORIGINAL_LOGIN()
       , USER
       ,SESSION_USER

REVERT

我認為您可以在不使用觸發器的情況下獲得相同的結果。您可以簡單地對更新過程進行一些小改動,如下所示

CREATE PROCEDURE test.spUpdatesRowInTestTableFirst
AS
   UPDATE test.TestTable
   SET Column1 = 'Updated ' +[Column1]
   , RowUpdatedBY = isnull(RowUpdatedBY, '') + object_name(@@procid) +',' -- adding this line to record the update
GO

但我們需要擴大你的桌子

$$ RowUpdateBy $$從目前 nvarchar(20) 到 NVARCHAR(2000) 的列以避免出現問題。

引用自:https://dba.stackexchange.com/questions/147093