2012-03-21 48 views
2

是否可以寫一個接受外部參數的觸發器?如何創建在SQL Server中接受外部參數的觸發器?

這樣做的主要原因是,我僅限於連接到使用只ONE數據庫用戶數據庫。現在我正在開發數據庫應用程序,併爲每個單獨的表創建觸發器以存儲歷史記錄。

雖然存儲歷史數據,我想存儲申請用戶名誰做了InsertUpdateDelete。我以爲使用User_Name()但知道,它只返回數據庫用戶,NOT應用程序用戶。

因此,我正在尋找一些關於使用外部參數創建觸發器的建議,以便我可以將應用程序用戶的ID傳遞給此觸發器。想想我已經清楚地解釋了我的需求。提前致謝 !

編輯
外部參數應該類似於存儲過程的參數一些地方我們可以通過價值

EDIT2
可能我的描述不夠清晰。所以我給你一個例子。
我正在開發的Web應用程序與帳戶相關。因此要跟蹤所需的數據更改。例如,賬戶人員可以更改員工的薪資和佣金信息。如果輸入/更新了錯誤的信息,那麼整體財務結果將會產生很大的負面影響。現在在系統中,用戶使用userid &密碼登錄系統,然後對員工信息進行一些更改。在這個階段,我想要保持這樣的軌跡:誰更改了員工信息,更改前的值以及更改前的值和更改完成後的值。所以,將來如果出現任何問題,我可以通過PROOF找出發生錯誤的用戶。
不一定,它應該使用觸發器來完成,但也歡迎任何其他選擇。

+0

什麼是「應用程序用戶ID」?它是SQL登錄,Windows帳戶還是其他? SYSTEM_USER是否返回你想要的或不? – Pondlife 2012-03-21 11:57:04

+0

你從哪裏獲得應用程序用戶?爲什麼你不能在觸發器內查找應用程序用戶? – adrianm 2012-03-21 11:58:05

+0

嘗試使用'CONTEXT_INFO()',嘗試使用[將一個變量傳遞給觸發器](http://stackoverflow.com/questions/2646547/pass-a-variable-into-a-trigger),請參閱鏈接以獲取答案使用這個。 – 2012-03-21 14:34:54

回答

5

你需要重新設計你的做法,有沒有辦法讓一個數據庫只知道任何有關應用程序的用戶的信息。而且,不,你不能傳遞參數給觸發器。但你可以從內部引用您自己的表格g觸發器,所以有一種方法...


當您連接到數據庫,每個連接獲得它自己的進程ID。你可以通過@@ spid獲得。

因此,當觸發器觸發時,您可以使用它來知道哪個連接導致更改。

你可以有100個併發連接使用同一個數據庫登錄,每個連接都有它自己的@@ spid值。


要做到這對你有用,但是,你需要準備所有的連接。每次建立連接時,應用程序都應該寫入一個表來記錄使用@@ spid的應用程序的使用情況。

或許真的那樣簡單......

CREATE TABLE 
    map_spid_application_user (
    spid   BIGINT, 
    application VARCHAR(128), 
    user   VARCHAR(128), 
    PRIMARY KEY (spid) 
) 

然後,每一個連接上,運行這樣的事情(也許通過存儲過程)...

DELETE map_spid_application_user WHERE spid = @@spid 

INSERT INTO map_spid_application_user SELECT @@spid, 'myApp', 'myUser' 


然後,在您的觸發器中,您可以引用/加入此表以找出@@ spid指的是誰。


您還可以得到更多的智能,並使用類似的方法來保持用戶的連接什麼的永久記錄,如什麼SPID。任何spid的當前用戶將始終是具有最近連接日期時間的用戶。


你幾乎可以做任何你喜歡的呢。因爲你正在創建所有的信息,而不依賴於數據庫只知道以外的任何東西都是@@ spid。

+0

我會試試這個 – 2012-03-22 04:09:42

1

將用戶名存儲在每個表中,並在數據更改期間將其作爲參數傳入。從那裏,觸發器可以將數據存檔到另一個表。

+0

「在每個表中存儲用戶名並在數據更改期間將其作爲參數傳遞」我對您想說的內容感到有些困惑。 ( – 2012-03-22 04:06:46

1

在你的地方,我將使用這個例子,如果在你的數據庫有人會做事件更新或選擇你將能夠添加一些信息,這就是你想要的。

示例表:

CREATE TABLE RAF1 
(
strona NUMBER, 
nazwa VARCHAR2(40) 
); 

例觸發(此觸發器將永遠如果你把nazw =「相同」由...寫=「羅蘭」它了連接到這個表可以編輯這個例子

create or replace TRIGGER sam 
BEFORE INSERT OR UPDATE OF nazwa 
ON RAF1 FOR EACH ROW WHEN (new.nazwa = 'same') 
BEGIN :new.nazwa := 'ronald'; END 
+1

這個問題是針對SQL-Server,而不是Oracle。 – MatBailie 2012-03-21 12:15:46

0

我已經完成了您所描述的內容。我不能說我對結果感到滿意,因爲解決方案可能會非常脆弱 - 當連接共享等奇怪事情發生時會中斷。它也只是感覺不對,但如果你喜歡嘗試。

  1. 在應用程序方面,東東的用戶名進入的ConnectionString的AppName的財產。
  2. 在觸發器中,引用App_Name()函數。

再次,這將做你所問,但我不推薦它。更好地管理審計信息,作爲客戶端或存儲過程的基本插入/更新內容的一部分。