将oracle触发器转换为ms sql触发器

时间:2013-07-18 03:57:13

标签: sql-server oracle triggers

我有一个oracle触发器:

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)可以类似地实现此触发器

但我不希望Id自动添加一个。

感谢。

1 个答案:

答案 0 :(得分:1)

  1. MS SQL不支持BEFORE个触发器。您应该使用INSTEAD OF触发器。
  2. MS SQL触发器是基于集合的触发器,而不是基于行的触发器,因此应该将其考虑在内
  3. 据说你可以尝试

    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 演示

    如果您想模拟允许插入明确指定的ID的部分WHEN (NEW."Id" IS NULL OR NEW."Id" = 0),那么

    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 演示