即使在 SSMA v 6.0 中关闭其生成,也会在触发器中生成 ROWID 列

Generation of ROWID column in triggers even when its generation is switched off in SSMA v 6.0

我使用 SSMA v6.0 将我的 Oracle 数据库迁移到 SQL Server 2014。

我关闭了 ROWID 列的生成,正如预期的那样,转换后它没有在我的任何 table 中生成任何额外的 ROWID 列,但令人惊讶的是它确实生成了与其各自相关的所有触发器 tables 与 ROWID 列注入触发器如下:

USE [DBName]
GO
/****** Object:  Trigger [dbo].[InsteadOfInsertOn$ROLEPERMISSIONS]    Script Date: 3/11/2015 10:58:46 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[InsteadOfInsertOn$ROLEPERMISSIONS]
   ON [dbo].[ROLEPERMISSIONS]
    INSTEAD OF INSERT
      AS 
         /*Generated by SQL Server Migration Assistant for Oracle version 6.0.0.*/
         BEGIN

        SET  NOCOUNT  ON

        DECLARE
           @triggerType char(1)

        SELECT @triggerType = 'I'

        /* column variables declaration*/
        DECLARE
           @new[=10=] uniqueidentifier, 
           @new$ROLEID decimal, 
           @new$MODULES_ACTIONSID decimal, 
           @new$ROLEPERMISSIONID decimal

        /* 
        *   SSMA error messages:
        *   O2SS0239: ROWID column is not accessible because the 'Generate ROWID' project setting is disabled.

        DECLARE
            ForEachInsertedRowTriggerCursor CURSOR LOCAL FORWARD_ONLY READ_ONLY FOR 
              SELECT ROWID, ROLEID, MODULES_ACTIONSID, ROLEPERMISSIONID
              FROM inserted            */


        /* 
        *   SSMA error messages:
        *   O2SS0174: The declaration of the identifier 'ForEachInsertedRowTriggerCursor' was converted with error(s).

        OPEN ForEachInsertedRowTriggerCursor            */

        /* 
        *   SSMA error messages:
        *   O2SS0174: The declaration of the identifier 'ForEachInsertedRowTriggerCursor' was converted with error(s).

        FETCH ForEachInsertedRowTriggerCursor
            INTO @new[=10=], @new$ROLEID, @new$MODULES_ACTIONSID, @new$ROLEPERMISSIONID            */

        WHILE @@fetch_status = 0
        BEGIN
              /* row-level triggers implementation: begin*/
              BEGIN
                 BEGIN
                    IF @triggerType = 'I'
                       SELECT @new$ROLEPERMISSIONID = NEXT VALUE FOR dbo.SEQ_ROLEPERMISSIONS
                 END
              END
              /* row-level triggers implementation: end*/

              /* 
              *   SSMA error messages:
              *   O2SS0239: ROWID column is not accessible because the 'Generate ROWID' project setting is disabled.

              /-* DML-operation emulation*-/
              INSERT dbo.ROLEPERMISSIONS(ROWID, ROLEID, MODULES_ACTIONSID, ROLEPERMISSIONID)
                 VALUES (@new[=10=], @new$ROLEID, @new$MODULES_ACTIONSID, @new$ROLEPERMISSIONID)                  */



              /* 
              *   SSMA error messages:
              *   O2SS0174: The declaration of the identifier 'ForEachInsertedRowTriggerCursor' was converted with error(s).

              FETCH ForEachInsertedRowTriggerCursor
                  INTO @new[=10=], @new$ROLEID, @new$MODULES_ACTIONSID, @new$ROLEPERMISSIONID                  */

           END

        /* 
        *   SSMA error messages:
        *   O2SS0174: The declaration of the identifier 'ForEachInsertedRowTriggerCursor' was converted with error(s).

        CLOSE ForEachInsertedRowTriggerCursor            */

        /* 
        *   SSMA error messages:
        *   O2SS0174: The declaration of the identifier 'ForEachInsertedRowTriggerCursor' was converted with error(s).

        DEALLOCATE ForEachInsertedRowTriggerCursor            */
     END

简而言之,问题是

  1. 关闭 ROWID 列生成后,它没有在任何 table 中创建任何 ROWID 列,而这恰恰是必需的

  2. 但它确实创建了所有触发器,就好像 table 中有 ROWID 列一样。

  3. 是的,它生成了触发器,并注释了所有需要 ROWID 的查询...(正如您从示例存储过程中看到的那样)

是否还有其他 way/option 我们也必须关闭触发器生成 ROWID?

您在 Oracle 中的触发器是 FOR EACH ROW。 SQL 服务器不直接支持这种类型的触发器。因此 SSMA 使用 INSTEAD OF 触发器为它们应用模板替换并循环 inserted.

您能否至少为带有触发器的表启用 ROWID(转换设置中的选项 "Add ROWID column for tables with triggers")?如果没有它,SSMA 不支持自动转换这种类型的触发器,否则您可能必须手动修改转换后的触发器。 (这就是为什么它仍然尝试尽可能多地进行转换,但保留对缺少的 ROWID 列的访问权限被注释掉的原因 - 因此您可以手动完成转换)。