2013-07-18 54 views
3

我有一個Oracle觸發器:轉換Oracle觸發器到MS SQL觸發

CREATE OR REPLACE TRIGGER "BI_Info" 
BEFORE INSERT ON "Info" FOR EACH ROW 
WHEN (NEW."Id" IS NULL OR NEW."Id" = 0) BEGIN 
    SELECT NVL(MAX("Id")+1, 1) INTO :NEW."Id" FROM "Info"; 
END; 

現在我想將它轉換爲MS SQL觸發器。

我知道[ID] [INT] IDENTITY(1,1)可以實現此觸發同樣

,但我不希望標識自動添加一個。

謝謝。

+0

什麼功能'NVL'嗎? –

+0

檢查「Id」是否爲空 – Rock

回答

1
  1. MS SQL不支持BEFORE觸發器。你應該使用INSTEAD OF觸發器。
  2. MS SQL觸發器設置爲基礎的,而不是基於行的觸發器,所以應考慮到

這就是說,你可以嘗試

CREATE TRIGGER tg_BI_Info_insert ON BI_Info 
INSTEAD OF INSERT AS 
BEGIN 
    DECLARE @max INT 

    SET @max = (SELECT COALESCE(MAX(id), 0) FROM BI_Info WITH (TABLOCKX, HOLDLOCK)) 

    INSERT INTO BI_Info (id, column1, ...) 
    SELECT @max + ROW_NUMBER() OVER (ORDER BY (SELECT 1)), column1, ... 
    FROM INSERTED 
END 

這裏是SQLFiddle演示

如果您想模擬零件WHEN (NEW."Id" IS NULL OR NEW."Id" = 0)允許插入明確分配的ID,然後

CREATE TRIGGER tg_BI_Info_insert ON BI_Info 
INSTEAD OF INSERT AS 
BEGIN 
    DECLARE @max INT 

    INSERT INTO BI_Info 
    SELECT * 
    FROM INSERTED 
    WHERE COALESCE(id, 0) <> 0 

    SET @max = (SELECT COALESCE(MAX(id), 0) FROM BI_Info WITH (TABLOCKX, HOLDLOCK)) 

    INSERT INTO BI_Info (id, column1) 
    SELECT @max + ROW_NUMBER() OVER (ORDER BY (SELECT 1)), column1 
    FROM INSERTED 
    WHERE COALESCE(id, 0) = 0 
END 

這裏是SQLFiddle演示了這種情況下