插入觸發器和主鍵的問題
我正在處理我無法更改或獲得支持的第 3 方應用程序。我以多種方式更改了基礎表以增強其功能
1-我將表 PRE_CASE 重命名為 PRE_TCASE
2-我創建了一個名為 PRE_CASE 的視圖,它是對 PRE_TCASE 的選擇,其中 UNION ALL 位於連結伺服器數據庫和名為 OTHERSYSTEM_CASE 的表上
當應用程序認為它正在查看表 PRE_CASE 時,它現在被欺騙向最終使用者顯示來自 PRE_TCASE 和 OTHERSYSTEM_CASE 的數據。但是,它在插入數據時失敗。為了嘗試解決這個問題,我創建了一個觸發器(我只需要插入 PRE_TCASE,而不是 OTHERSYSTEM_CASE)
create TRIGGER INSREPLACE ON dbo.pre_case INSTEAD OF INSERT AS BEGIN SET NOCOUNT ON; INSERT INTO dbo.PRE_TCASE (col1, col2, col3, etc.) SELECT col1, col2, col3, etc. FROM Inserted END
我在插入失敗時出現錯誤:
消息 233,級別 16,狀態 2,第 1 行表 ‘dbo.pre_case’ 中的列 ‘ID’ 不能為空。
插入語句的形式為
INSERT INTO dbo.pre_case (col1, col2, col3) values (1,2,3)
沒有對 ID 列進行任何值/引用。
在底層 PRE_CASE 上,列 ID 是具有有效身份種子的整數主鍵(PK、int、非空)。直接插入到 PRE_CASE 可以工作,但不能直接插入到新視圖和触發器上。我忽略了什麼?
(我的最終解決方案將部署到 SQL2000、SQL2005 和 SQL2008R2 機器上,但我正在 SQL2000 上進行測試/開發)
編輯:我創建了這個模型以更孤立的方式進行測試。結果發現錯誤發生在 SQL2000 而不是 SQL2008R2 上,我個人現在放棄了。
create table t1(id int IDENTITY(1,1) PRIMARY KEY ,ltext varchar(100)); create table t2(id int IDENTITY(1,1) PRIMARY KEY,ltext varchar(100)); CREATE VIEW tv AS SELECT id, ltext from t1 union all SELECT id, ltext from t2 select * from t2; select * from tv; INSERT t1(ltext) values ('test1a'); INSERT t1(ltext) values ('test1b'); INSERT t1(ltext) values ('test1c'); INSERT t2(ltext) values ('test2a'); INSERT t2(ltext) values ('test2b'); INSERT t2(ltext) values ('test2c'); CREATE TRIGGER TRG_TV ON tv INSTEAD OF INSERT AS BEGIN SET NOCOUNT ON INSERT t2(ltext) select ltext from inserted END -- this errors on SQL2000 INSERT tv(ltext) values ('testv-a');
起初我認為這是由於
INSERT INTO
你正在做的 pre_case,而不是INSERT INTO
觸發器。但在提供了更多資訊後,事實並非如此。從Google結果來看,這是
INSTEAD OF
觸發器的常見錯誤,可能是標識列。當觸發器觸發時,該列的值尚未生成INTEAD OF
,因此 ID 為 NULL。將列更改為可為空,然後查看您在新表的 ID 列中得到什麼。如果你有它的價值,那麼你很高興。如果你不這樣做,似乎你需要生成它。(我的最終解決方案將部署到 SQL2000、SQL2005 和 SQL2008R2 機器上,但我正在 SQL2000 上進行測試/開發)
瘋狂的
這不能在 SQL2000 下工作。如果您提供一個虛擬 ID 值:
INSERT tv(id, ltext) values (0, 'testv-a');
然後它將起作用,0 將被忽略並生成一個標識值。但正如問題場景所述,插入語句是由第 3 方執行檔設置的,那麼它是不可行的。