【问题标题】:How can I convert the following oracle trigger to SQL Server trigger?如何将以下 oracle 触发器转换为 SQL Server 触发器?
【发布时间】:2017-12-15 10:55:29
【问题描述】:

我想将 Oracle 数据库迁移到 SQL Server。 我已使用 SQL Server 迁移助手转换数据库,但触发器无法正常工作。

如何将以下 oracle 触发器转换为 SQL Server 触发器?

create or replace TRIGGER "PEXLATEST".TRG_TCM_BEF_INS_UPD BEFORE INSERT OR UPDATE OR DELETE ON TYPE_CODE_MASTER REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
L_COUNT NUMBER:=0;
BEGIN
IF(INSERTING) THEN
  SELECT COUNT(1) INTO L_COUNT FROM TYPE_CODE_MASTER
  WHERE TCM_TYPE=:NEW.TCM_TYPE
  AND (TCM_NAME_E=:NEW.TCM_NAME_E OR TCM_NAME_A=:NEW.TCM_NAME_A);
  IF L_COUNT>0 THEN
     raise_application_error( -20001, 'Duplicate Name');
  END IF;
END IF;
IF (UPDATING) THEN
SELECT COUNT(1) INTO L_COUNT FROM TYPE_CODE_MASTER
  WHERE TCM_TYPE=:NEW.TCM_TYPE
  AND (TCM_NAME_E=:NEW.TCM_NAME_E OR TCM_NAME_A=:NEW.TCM_NAME_A)
  AND TCM_ID<>:NEW.TCM_ID;
  IF L_COUNT>0 THEN
     raise_application_error( -20001, 'Duplicate Name');
  END IF;
END IF;
IF (DELETING) THEN
IF :OLD.TCM_TYPE='ICTG' THEN
SELECT COUNT(1) INTO L_COUNT FROM ITEM
  WHERE ITM_CATEGORY_TYPE_ID=:OLD.TCM_ID;
  IF L_COUNT>0 THEN
     raise_application_error( -20002, 'Item Category referred in Items');
  END IF;
  END IF;
END IF;
END;

【问题讨论】:

  • 到目前为止您尝试过什么,或者您希望我们为您完成这项工作?
  • 创建 3 个触发器(每个插入、删除、更新 1 个),删除双引号。阅读信号 sqlstate。
  • 提示:inserteddeleted 是表,因此它们可以表示集合操作的结果。假设触发器总是只处理一行,而设计触发器通常是一个糟糕的计划。如果您绝对确定不会超过一排,那么添加对行数的检查,并使用RaIsErrorThrow 明确告知以后来的人他们有试图执行不可接受的语句。 (if ( select Count(*) from inserted ) &gt; 1 RaIsError( 'FooTable_Insert: No more than one row may be processed.', 25, 42 ) with log)

标签: sql-server tsql database-trigger


【解决方案1】:

检查我编写的代码对我来说非常困难,但可能是这样的:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [PEXLATEST].[TRG_TCM_BEF_INS_UPD]
   ON TYPE_CODE_MASTER
   AFTER INSERT,DELETE,UPDATE
AS 
BEGIN
    SET NOCOUNT ON;


    IF EXISTS(SELECT 1 FROM inserted)
       BEGIN
            -- insert or update, check same condition in your code
            -- new rows are already inserted or updated because trigger execute always AFTER
            IF EXISTS(SELECT 1 FROM TYPE_CODE_MASTER 
                      WHERE TCM_TYPE IN (SELECT TCM_TYPE FROM inserted)
                      GROUP BY TCM_NAME_E
                      HAVING COUNT(*) > 1)
               OR EXISTS(SELECT 1 FROM TYPE_CODE_MASTER 
                        WHERE TCM_TYPE IN (SELECT TCM_TYPE FROM inserted)
                        GROUP BY TCM_NAME_A
                        HAVING COUNT(*) > 1)       

               BEGIN
                    RAISERROR('Duplicate Name', 16, 1);
                    ROLLBACK TRAN;
                    RETURN;
               END 
       END
    ELSE
       BEGIN
        -- delete
        IF EXISTS(SELECT 1 FROM deleted AS D
              INNER JOIN ITEM AS I ON I.ITM_CATEGORY_TYPE_ID = D.TCM_ID
              )
            BEGIN
                    RAISERROR('Item Category referred in Items', 16, 1);
                    ROLLBACK TRAN;
                    RETURN;
            END
       END
END
GO

【讨论】:

    猜你喜欢
    • 2019-04-08
    • 1970-01-01
    • 2020-07-15
    • 2011-09-11
    • 2013-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多