none
Sql dinamico em Trigger RRS feed

  • Pergunta

  • Boa tarde pessoal.

    Estou criando uma trigger after update e preciso criar uma query dinamica, acessando as tabelas DELETED e INSERTED, da segiunte maneira:

    CREATE TRIGGER ...
    ...

    SET @SQL = @SQL + ' SELECT ''FLAG'', A.FLAG, B.FLAG'
    SET @SQL = @SQL + ' FROM DELETED AS A INNER JOIN INSERTED AS B ON A.COD = B.COD'

    EXEC(@SQL)

    .......................

    Ou seja, quero pegar um campo da tabela DELETED e outro da INSERTED. Ao executar o UPDATE nessa tabela, o seguinte erro é retornado:

    Msg 208, Level 16, State 1, Line 1
    Invalid object name 'DELETED'.


    Se eu executar a query direto, sem o EXEC, funciona. Alguem poderia dar uma luz sobre o que pode estar acontecendo? O EXEC nao reconhe a tabela DELETED e INSERTED dentro de uma trigger?

    Abçs e obrigado desde já!

    segunda-feira, 23 de março de 2009 18:56

Respostas

  • no caso que tu apresentou ficaria mais ou menos assim:

    CREATE TRIGGER ...
    ...

    CREATE TABLE #TABELA(CAMPO1 NVARCHAR(100)) -- AQUI OS CAMPOS DE ACORDO COM A INSERTED

    INSERT INTO #TABELA SELECT * FROM INSERTED

    SET @SQL = @SQL + ' SELECT ''FLAG'', A.FLAG, B.FLAG'
    SET @SQL = @SQL + ' FROM DELETED AS A INNER JOIN #TABELA AS B ON A.COD = B.COD'

    EXEC SP_EXECUTESQL @SQL


    Anderson Rodrigues
    • Marcado como Resposta fvilelaRJ terça-feira, 24 de março de 2009 13:15
    segunda-feira, 23 de março de 2009 20:03

Todas as Respostas

  • eu creio que não dê pra fazer dessa forma... o comando EXEC abre outra seção no SQL Server, e nesta outra seção, ele não consegue acessar DELETED nem INSERTED...
    Anderson Rodrigues
    segunda-feira, 23 de março de 2009 19:37
  • Exato, por isso nesse momento tentei utilizar o SP_EXECUTESQL, que nao abre outra seção, mas mesmo assim, o erro persistiu. Ele nao deveria funcionar com o comando:

    Exec Sp_executesql @sql , ja que o mesmo nao abre outra secao?
    segunda-feira, 23 de março de 2009 19:38
  • cara, tu pode criar uma tabela temporaria na trigger e jogar o conteudo da deleted pra ela... eu fiz um exemplo aqui, talvez te ajude...

    Create Table __TESTE(
    DESCR varchar(100)
    )
    GO

    Create Table __TESTE_2(
    DESCR varchar(100)
    )
    GO

    Alter Trigger TR_TESTE On  __TESTE After Insert
    As
    Declare
    @SQL nvarchar(1000)
    Begin
    Create Table #TABELA(DESCR varchar(1000))
    Insert Into #TABELA(DESCR) Select DESCR From INSERTED
    Set @SQL = 'Insert Into __TESTE_2(DESCR) Select DESCR From #TABELA'
    Exec sp_executesql @SQL
    End
    GO

    Insert Into __TESTE(DESCR) Values('TESTE2')
    GO

    Select * From __TESTE
    Select * From __TESTE_2


    Anderson Rodrigues
    segunda-feira, 23 de março de 2009 19:56
  • no caso que tu apresentou ficaria mais ou menos assim:

    CREATE TRIGGER ...
    ...

    CREATE TABLE #TABELA(CAMPO1 NVARCHAR(100)) -- AQUI OS CAMPOS DE ACORDO COM A INSERTED

    INSERT INTO #TABELA SELECT * FROM INSERTED

    SET @SQL = @SQL + ' SELECT ''FLAG'', A.FLAG, B.FLAG'
    SET @SQL = @SQL + ' FROM DELETED AS A INNER JOIN #TABELA AS B ON A.COD = B.COD'

    EXEC SP_EXECUTESQL @SQL


    Anderson Rodrigues
    • Marcado como Resposta fvilelaRJ terça-feira, 24 de março de 2009 13:15
    segunda-feira, 23 de março de 2009 20:03
  • Olá Vilela,

    VOcê vai usar estes dados pra que?

    Se for pra dar um update em outra table, você pode usar o update com join diretamente.

    Abraços
    Demétrio Silva
    segunda-feira, 23 de março de 2009 20:05
  • Na realidade ire fazer isso para as duas tabelas, tanto a Deleted como a Inserted, já que ambas sao criadas em tempo de execucao do update. Valeu pela dica cara, vou fazer isso.

    Um forte abraço!
    segunda-feira, 23 de março de 2009 20:06
  • Não, Demétrio, vou explicar.

    Estou criando um ambiente de controle de atualizações das tabelas de um banco. Existe uma tabela de auditoria que armazenará informações de cada registro que foi alterado, com o dado antes e pos update. A estrutura da tabela é a seguinte:

    st1\:*{behavior:url(#ieooui) }

    A TB_HISTORICO_ATUALIZACAO

     

                [SEQ_HISTORICO_OPERACAO] – Sequencia do registro.

                [NOM_OBJETO]                         - Nome da tabela que está sofrendo alteração.

                    [COD_IDENTIFICADOR]                   - Campo chave do registro

                [NOM_COLUNA]                         - Nome da coluna que está sofrendo alteração.

                [DSC_CAMPO_ANTIGO]             - Valor do registro antes da atualização.

                [DSC_CAMPO_NOVO]               - Valor do registro após a atualização.

                [DAT_OPERACAO]                     - Data da operação

    [NOM_USUARIO]                       - Usuário que realizou a operação.


    Entendeu?


    E a questao da query dinamica é por que, se o usuário atualizar 3 campos de um registro, eu preciso inserir 3 registros nessa tabela, ou seja, eu preciso verificar campo a campo se houve update, e para cada campo, inserir um registro diferente, por isso criar uma query dinamica onde passarei por variavel o nome do campo que ele deve buscar os dados.

    Abçs

    segunda-feira, 23 de março de 2009 20:09