Compartilhar via


O2SS0239: Coluna ROWID não acessível (erro)

Este artigo descreve o motivo pelo qual o Assistente de Migração do SQL Server (SSMA) para Oracle requer que uma ROWID coluna seja definida para a tabela com disparadores.

Tela de fundo

No Oracle, você pode criar um gatilho que é executado FOR EACH ROW, em vez de para todo o conjunto de linhas que está mudando. No SQL Server, os gatilhos sempre são executados para todo o conjunto de linhas modificadas. Se o acionador Oracle em nível de linha acessar variáveis especiais e :old :new variáveis, o SSMA precisará de uma maneira de corresponder linhas de ambos os conjuntos de linhas para identificar qual era o valor de uma determinada linha antes e depois da atualização. Para emular essa funcionalidade "para cada linha", o SSMA adiciona uma coluna especial ROWID para identificar exclusivamente cada linha modificada e usa essa coluna para estabelecer uma relação entre os conjuntos de linhas inserted e deleted.

Esse comportamento é controlado pela configuração de projeto Gerar coluna ROWID, que pode ser encontrada em Ferramentas - Configurações do Projeto - Geral - Conversão - Geração de ROWID. Se a configuração estiver definida como Não, a ROWID coluna não será adicionada à tabela e o SSMA não poderá converter esses gatilhos.

Exemplo

O seguinte gatilho Oracle é executado para cada linha atualizada na TRIG_TEST tabela:

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;

Quando você tenta converter esse gatilho no SSMA, se a configuração de projeto de coluna Gerar ROWID estiver definida como Não, SSMA gera a seguinte mensagem de erro:

O2SS0239: Coluna ROWID não acessível

Possíveis soluções

Altere a configuração do projeto de coluna Gerar ROWID para Adicionar coluna ROWID para tabelas com disparadores, o que permite que o SSMA produza o seguinte T-SQL no gatilho do SQL Server ao converter o exemplo anterior:

  1. Execute um cursor sobre o conjunto de linhas inserted, selecionando as colunas ROWID e DATA nas variáveis @new$0 e @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
    
  2. Selecione a linha correspondente ao conjunto de linhas deleted configurado nas variáveis @old$0 e @old$DATA, com base na ROWID inserida (armazenada na variável @new$0):

    SELECT @old$0 = ROWID, @old$DATA = DATA
    FROM deleted
    WHERE ROWID = @new$0
    
  3. Execute ações de gatilho usando as variáveis @old$DATA/@new$DATA:

    IF (@new$DATA = 'ABC')
        INSERT SSMAADMIN.TRIG_TEST(DATA)
        VALUES (('-' + ISNULL(@old$DATA, '')))