Sql-Server

插入觸發器和主鍵的問題

  • October 4, 2017

我正在處理我無法更改或獲得支持的第 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 方執行檔設置的,那麼它是不可行的。

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