本文介绍 Oracle 的 SQL Server 迁移助手 (SSMA) 向表中添加ROWID
列的原因(如果有触发器)。
背景
在 Oracle 中,可以创建一个运行 FOR EACH ROW
触发器,而不是针对正在更改的整个行集。 在 SQL Server 中,触发器始终针对整个修改的行集执行。 如果行级 Oracle 触发器同时访问 - :old
和 :new
特殊变量,则 SSMA 需要一种方法来匹配这两个行集中的行,以便标识更新前后给定行的值。 为了模拟每个行功能,SSMA 会添加特殊ROWID
列来唯一标识每个修改的行,并使用它在行deleted
集之间建立inserted
关系。
示例
在以下示例中,Oracle 触发器针对表中更新 TRIG_TEST
的每一行执行:
CREATE OR REPLACE TRIGGER TSCHM.TRIG_TEST_AU
AFTER UPDATE OF DATA ON TSCHM.TRIG_TEST
FOR EACH ROW
BEGIN
IF (:new.DATA = 'ABC') THEN
INSERT INTO TSCHM.TRIG_TEST(DATA) VALUES ('-' || :old.DATA);
END IF;
END;
尝试在 SSMA 中转换此触发器时,在 SQL Server 触发器中生成以下 T-SQL:
对
inserted
行集运行游标,将ROWID
和DATA
列选为@new$0
和@new$DATA
变量:DECLARE ForEachInsertedRowTriggerCursor CURSOR LOCAL FORWARD_ONLY READ_ONLY FOR SELECT ROWID, DATA FROM inserted OPEN ForEachInsertedRowTriggerCursor FETCH ForEachInsertedRowTriggerCursor INTO @new$0, @new$DATA
在循环中,根据插入
ROWID
的行(存储在变量中@new$0
)从行集中@old$0
选择匹配行deleted
和@old$DATA
变量:SELECT @old$0 = ROWID, @old$DATA = DATA FROM deleted WHERE ROWID = @new$0
使用
@old$DATA
/@new$DATA
变量执行触发器操作:IF (@new$DATA = 'ABC') INSERT SSMAADMIN.TRIG_TEST(DATA) VALUES (('-' + ISNULL(@old$DATA, '')))
其他信息
此行为由“生成 ROWID 列”项目设置控制,位于“工具”>“项目设置”>“常规”>“转换”>“ROWID 生成”下。 如果设置设置为 “否”,但在触发器转换 SSMA 期间标识它需要列 ROWID
,则会 生成O2SS0239 转换错误。
相关的转换消息
- O2SS0239:无法访问 ROWID 列(错误)
- O2SS0267:ROWID 列
- O2SS0404:无法转换 ROWID 列