2010-09-16 40 views
0

我有MS SQL Server數據庫並將一些值插入其中一個表中。如何不將特定值插入到數據庫

假設該表格包含列ID,int Statustext Text

如果可能,我想創建一個觸發器來防止寫入特定不正確的狀態(比如1)到表中。應該寫入0。但是,在插入新值時應保留其他列:

如果寫入的新行是(1, 4, "some text"),則會按原樣寫入。
如果寫入新行(1, 1, "another text"),它被寫爲(1, 0, "another text"

是否有可能創造這樣的觸發?怎麼樣?

編輯:即使狀態欄無效,我也需要寫這樣的記錄,所以外鍵不適用於我。

+0

絕對是。插入觸發器可以做到這一點。然而,由於各種原因,主要與易於調試和可維護性有關,我建議你在代碼中處理它,而不是使用這種邏輯的觸發器。另外,如果狀態是用戶輸入,那麼如果輸入的狀態不正確,您是否需要警告/警告用戶,而不是僅僅將用戶更改爲未知狀態? – InSane 2010-09-16 06:21:17

+1

我正在使用ORM寫入數據庫,並且在插入具有中間狀態的中間值時會出現一些情況。但這並不算太糟糕,但是,如果由於某些原因程序崩潰,則無效狀態將存儲在數據庫中。所以我不能在代碼中處理這個(這是第三方二進制文件),這不是用戶輸入。 – Alex 2010-09-16 06:47:29

+0

使用交易以確保ACID儘可能... – 2010-09-16 06:55:31

回答

2

我想你需要一個外鍵來保證數據的完整性,即使你選擇使用觸發器(雖然我自己更喜歡'助手'存儲過程觸發器會導致調試地獄)。

CREATE TABLE MyStuff 
(
ID INTEGER NOT NULL UNIQUE, 
Status INTEGER NOT NULL 
    CHECK (Status IN (0, 1)), 
UNIQUE (Status, ID) 
); 

CREATE TABLE MyZeroStuff 
(
ID INTEGER NOT NULL, 
Status INTEGER NOT NULL 
    CHECK (Status = 0), 
FOREIGN KEY (Status, ID) 
    REFERENCES MyStuff (Status, ID), 
my_text VARCHAR(20) NOT NULL 
); 

CREATE TRIGGER tr__MyZeroStuff 
ON MyZeroStuff 
INSTEAD OF INSERT, UPDATE 
AS 
BEGIN; 
INSERT INTO MyZeroStuff (ID, Status, my_text) 
SELECT i.ID, 0, i.my_text 
    FROM inserted AS i; 
END; 
+0

謝謝,onedaywhen! – Alex 2010-09-16 07:52:27

0

插入觸發器已被提及,但實現此目的的另一種方法是在Status列上有一個指向狀態表的foriegn鍵 - 這將不允許寫入和更改值,而只是簡單地如果foriegn鍵無效,則禁止寫入。

有關此選項的更多信息,請查看referential integrity

+0

謝謝你的回答,但微妙的是,由於任務的具體情況,我需要允許編寫這樣的記錄,即使狀態欄無效,因此外鍵也不適用於我。 – Alex 2010-09-16 06:44:36