[firebase-br] RES: RES: RES: Extrair trigger em .txt via procedure

Alexandre camilo em apollosistemas.com.br
Qua Dez 5 11:48:09 -03 2012


Marcos não sei se vc  já resolveu ai, caso queira dar uma olhada tenho um
script que cria o que utilizo aqui.  Obs testei no firebird 2.5

//---------------------- inicio 

--CREATE OR ALTER PROCEDURE CRIAR_LOG
EXECUTE BLOCK
AS
DECLARE VARIABLE TABELA VARCHAR(100);
DECLARE VARIABLE STMT VARCHAR(30000);
DECLARE VARIABLE QTD INTEGER;
DECLARE VARIABLE CAMPO VARCHAR(100);
begin

    /* CRIANDO TABELAS DE LOG */
    SELECT COUNT(*) FROM RDB$RELATIONS WHERE RDB$RELATION_NAME =
'LOG$MASTER' INTO QTD;
    if (QTD = 0) then
    BEGIN
        EXECUTE STATEMENT('
        CREATE TABLE LOG$MASTER (
            ID         INTEGER NOT NULL PRIMARY KEY,
            DATAHORA   TIMESTAMP NOT NULL,
            USUARIO    VARCHAR(255) NOT NULL,
            TABELA     VARCHAR(255) NOT NULL,
            OPERACAO   VARCHAR(6) NOT NULL,
            PK1        VARCHAR(255),
            PK1_VALOR  VARCHAR(255),
            PK2        VARCHAR(255),
            PK2_VALOR  VARCHAR(255),
            PK3        VARCHAR(255),
            PK3_VALOR  VARCHAR(255),
            PK4        VARCHAR(255),
            PK4_VALOR  VARCHAR(255),
            PK5        VARCHAR(255),
            PK5_VALOR  VARCHAR(255),
            IP         VARCHAR(255)
        )');

        UPDATE RDB$RELATIONS SET RDB$SYSTEM_FLAG = 1 WHERE
(RDB$RELATION_NAME = 'LOG$MASTER');
    END

    SELECT COUNT(*) FROM RDB$RELATIONS WHERE RDB$RELATION_NAME =
'LOG$DETALHE' INTO QTD;
    if (QTD = 0) then
    BEGIN
        EXECUTE STATEMENT(
        'CREATE TABLE LOG$DETALHE (
            ID            INTEGER NOT NULL REFERENCES LOG$MASTER,
            COLUNA        VARCHAR(255),
            VALOR_ANTIGO  VARCHAR(2000),
            VALOR_NOVO    VARCHAR(2000)
        )');

        UPDATE RDB$RELATIONS SET RDB$SYSTEM_FLAG = 1 WHERE
(RDB$RELATION_NAME = 'LOG$DETALHE');
    END

    SELECT COUNT(*) FROM RDB$GENERATORS WHERE RDB$GENERATOR_NAME =
'GEN_LOG_MASTER_ID' INTO QTD;
    if (QTD = 0) then
    BEGIN
        EXECUTE STATEMENT ('CREATE GENERATOR GEN_LOG_MASTER_ID');
    END

    SELECT COUNT(*) FROM RDB$PROCEDURES WHERE RDB$PROCEDURE_NAME =
'P_LOG$MASTER_I' INTO QTD;
    if (QTD = 0) then
    BEGIN
            STMT =
                'CREATE OR ALTER PROCEDURE P_LOG$MASTER_I (
                    USUARIO VARCHAR(100),
                    TABELA VARCHAR(31),
                    OPERACAO VARCHAR(6),
                    PK1 VARCHAR(31),
                    PK1_VALOR VARCHAR(100),
                    PK2 VARCHAR(31),
                    PK2_VALOR VARCHAR(100),
                    PK3 VARCHAR(31),
                    PK3_VALOR VARCHAR(100),
                    PK4 VARCHAR(31),
                    PK4_VALOR VARCHAR(100),
                    PK5 VARCHAR(31),
                    PK5_VALOR VARCHAR(100),
                    IP VARCHAR(255))
                RETURNS (
                    VAR_ID INTEGER)
                AS
                BEGIN
                    VAR_ID = GEN_ID(GEN_LOG_MASTER_ID,1);
                    USUARIO = rdb$get_context(''USER_SESSION'',
''USUARIO'');
                    IF (USUARIO IS NULL) THEN     USUARIO = USER;
                    INSERT INTO LOG$MASTER(ID, DATAHORA, USUARIO, TABELA,
OPERACAO, PK1, PK1_VALOR, PK2, PK2_VALOR, PK3, PK3_VALOR, PK4, PK4_VALOR,
PK5, PK5_VALOR, IP)
                    VALUES (:VAR_ID, CURRENT_TIMESTAMP , :USUARIO, :TABELA,
:OPERACAO, :PK1, :PK1_VALOR, :PK2,   :PK2_VALOR, :PK3, :PK3_VALOR, :PK4,
:PK4_VALOR, :PK5, :PK5_VALOR, :IP); END';

            EXECUTE STATEMENT(:STMT);
    END

    SELECT COUNT(*) FROM RDB$PROCEDURES WHERE RDB$PROCEDURE_NAME =
'P_LOG$DETALHE_I' INTO QTD;
    if (QTD = 0) then
    BEGIN
        EXECUTE STATEMENT (
        'CREATE OR ALTER PROCEDURE P_LOG$DETALHE_I (
            ID INTEGER,
            COLUNA VARCHAR(50),
            VALOR_ANTIGO VARCHAR(2000),
            VALOR_NOVO VARCHAR(2000))
        AS
        BEGIN
            INSERT INTO LOG$DETALHE(ID, COLUNA, VALOR_ANTIGO, VALOR_NOVO)
            VALUES (:ID, :COLUNA, :VALOR_ANTIGO, :VALOR_NOVO);
        END');
    END

    /* CRIANDO TRIGGERS DAS TABELAS */
    FOR SELECT RDB$RELATION_NAME FROM RDB$RELATIONS WHERE RDB$SYSTEM_FLAG =
0 INTO TABELA DO
    BEGIN
        TABELA = TRIM(TABELA);
        SELECT COUNT(*) FROM RDB$TRIGGERS WHERE RDB$TRIGGER_NAME =
'LOG_'||:TABELA INTO QTD;
        if (QTD = 0) then
        BEGIN
            STMT =
                'CREATE OR ALTER TRIGGER LOG_'||TABELA||' FOR '||TABELA||'
                ACTIVE AFTER INSERT OR UPDATE OR DELETE POSITION 32767
                AS 
                DECLARE VARIABLE
                 VAR_ID INTEGER; 
                BEGIN 
                        EXECUTE PROCEDURE P_LOG$MASTER_I
(NULL,'''||TABELA||''',CASE WHEN (UPDATING) THEN ''UPDATE'' WHEN (INSERTING)
THEN ''INSERT'' ELSE ''DELETE'' END ';

            QTD = 1;
            FOR SELECT SEG.RDB$FIELD_NAME FROM RDB$RELATION_CONSTRAINTS CNT
INNER JOIN RDB$INDEX_SEGMENTS SEG ON CNT.RDB$INDEX_NAME = SEG.RDB$INDEX_NAME
                        WHERE CNT.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' AND
(CNT.RDB$RELATION_NAME = :TABELA) INTO CAMPO DO
            BEGIN
                CAMPO = TRIM(CAMPO);
                if (QTD <= 5) then
                BEGIN
                    STMT = STMT ||','''|| CAMPO|| ''', CASE WHEN (UPDATING
OR DELETING) THEN OLD.'||CAMPO||' ELSE NEW.'||CAMPO|| ' END';
                    QTD = QTD + 1;
                END
            END

            if (QTD <= 5) then
            BEGIN
                FOR SELECT RDB$FIELD_NAME
                    FROM RDB$INDICES IDX
                        INNER JOIN RDB$INDEX_SEGMENTS CMP ON
IDX.RDB$INDEX_NAME = CMP.RDB$INDEX_NAME
                        INNER JOIN RDB$RELATION_CONSTRAINTS CNT ON
IDX.RDB$INDEX_NAME = CNT.RDB$INDEX_NAME
                    WHERE (IDX.RDB$RELATION_NAME = :TABELA) AND
(CNT.RDB$CONSTRAINT_TYPE <> 'PRIMARY KEY') INTO CAMPO DO
                BEGIN
                    CAMPO = TRIM(CAMPO);
                    if (QTD <= 5) then
                    BEGIN
                        STMT = STMT ||','''|| CAMPO|| ''', CASE WHEN
(UPDATING OR DELETING) THEN OLD.'||CAMPO||' ELSE NEW.'||CAMPO|| ' END';
                        QTD = QTD + 1;
                    END
                END
            END

            WHILE (QTD <= 5) DO
            BEGIN
                STMT = STMT || ', NULL, NULL';
                QTD = QTD + 1;
            END
            STMT = STMT || ', rdb$get_context(''SYSTEM'',
''CLIENT_ADDRESS'')) RETURNING_VALUES VAR_ID;';

            FOR SELECT RDB$RELATION_FIELDS.RDB$FIELD_NAME FROM
RDB$RELATION_FIELDS WHERE RDB$RELATION_FIELDS.RDB$RELATION_NAME = :TABELA
INTO CAMPO DO
            BEGIN
                CAMPO = TRIM(CAMPO);
                STMT = STMT || ' IF (OLD.'||CAMPO||' IS DISTINCT FROM
NEW.'||CAMPO||') THEN EXECUTE PROCEDURE P_LOG$DETALHE_I(:VAR_ID,
'''||CAMPO||''', OLD.'||CAMPO||', NEW.'||CAMPO||'); ';
            END

            STMT = STMT || ' END';


            EXECUTE STATEMENT (STMT);
        END
    END

end;


//--------------------- fim 





-----Mensagem original-----
De: lista [mailto:lista-bounces em firebase.com.br] Em nome de Marcos Weimer
Enviada em: segunda-feira, 3 de dezembro de 2012 14:27
Para: FireBase
Assunto: Re: [firebase-br] RES: RES: Extrair trigger em .txt via procedure

O meu é bem parecido, aqui o atualizador automatico esta "no forno", o
problema é o pessoal do suporte mesmo que insiste em rodar script direto no
ibexpert, por isso pensei em uma procedure para desativar e outra para
criar, remover as triggers é tranquilo, o problema é montar elas pq em
muitas tabelas estoura o limite da variavel varchar e isto não estou
conseguindo resolver.

-=Ma®©oS=-
Marcos R. Weimer
Delphi / C# / ASP.NET / WebServices / Firebird




Em 3 de dezembro de 2012 14:21, Alexandre
<camilo em apollosistemas.com.br>escreveu:

> Não sei como funciona ai, mas no meu caso, criei uma rotina somente para
> atualização do banco, e é tudo "automático",  o usuário mesmo, clica em
> atualizar estruturas e o sistema faz todos os procedimentos necessários,
> exclui as triggers, adiciona/deleta/ altera campos, renomeia enfim, faz
> todas as operações necessárias e depois recrio as triggers.
> Eu criei o banco de LOGS, baseado em alguns exemplos que encontrei na
> internet mesmo, utilizando um schema master/detail, onde na máster gravo
> alguma coisa para que eu possa identificar o registro unicamente e no
> detail
> gravo as alterações de todos os campos, se o seu schema for algo parecido
> posso lhe enviar um exemplo.
>
>
> Alexandre
>
>
>
> -----Mensagem original-----
> De: lista [mailto:lista-bounces em firebase.com.br] Em nome de Marcos Weimer
> Enviada em: segunda-feira, 3 de dezembro de 2012 14:06
> Para: FireBase
> Assunto: Re: [firebase-br] RES: Extrair trigger em .txt via procedure
>
> Tambem crio as triggers de log dentro do delphi em uma tela o usuario pode
> escolher as tabelas e o tipo do log (insert/update/delete).
>
> Meu problema está no pessoal do suporte, que esquece de desativar/remover
o
> log, atualizar o banco e depois ativar/recriar o log.
>
>
>
> -=Ma®©oS=-
> Marcos R. Weimer
> Delphi / C# / ASP.NET / WebServices / Firebird
>
>
>
>
> Em 3 de dezembro de 2012 13:53, Alexandre
> <camilo em apollosistemas.com.br>escreveu:
>
> > No meu caso, utilizo o Delphi, eu fiz uma rotina para criar as triggers
> de
> > log dentro do delphi, assim como a criação de campos, antes de atualizar
> as
> > estruturas, faço um DROP nas triggers e depois recrio-as apenas chamando
> a
> > função.
> >
> >
> >
> > -----Mensagem original-----
> > De: lista [mailto:lista-bounces em firebase.com.br] Em nome de Marcos
> Weimer
> > Enviada em: segunda-feira, 3 de dezembro de 2012 11:19
> > Para: FireBase
> > Assunto: Re: [firebase-br] Extrair trigger em .txt via procedure
> >
> > Sim, o problema neste caso de desativar é que se foi adicionado campos
na
> > tabela, a trigger de log não vai estar preparada para este novo campo,
> > teria de ser refeita/compilada.
> >
> >
> > -=Ma®©oS=-
> > Marcos R. Weimer
> > Delphi / C# / ASP.NET / WebServices / Firebird
> >
> >
> >
> >
> > Em 3 de dezembro de 2012 11:15, Gladiston Santana
> > <gladiston em vidy.com.br>escreveu:
> >
> > > ois que aprender como fazer isso, voce pode criar uma SP e com
> > ______________________________________________
> > FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> > Para saber como gerenciar/excluir seu cadastro na lista, use:
> > http://www.firebase.com.br/fb/artigo.php?id=1107
> > Para consultar mensagens antigas: http://firebase.com.br/pesquisa
> >
> >
> > ______________________________________________
> > FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> > Para saber como gerenciar/excluir seu cadastro na lista, use:
> > http://www.firebase.com.br/fb/artigo.php?id=1107
> > Para consultar mensagens antigas: http://firebase.com.br/pesquisa
> >
> ______________________________________________
> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> Para saber como gerenciar/excluir seu cadastro na lista, use:
> http://www.firebase.com.br/fb/artigo.php?id=1107
> Para consultar mensagens antigas: http://firebase.com.br/pesquisa
>
>
> ______________________________________________
> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> Para saber como gerenciar/excluir seu cadastro na lista, use:
> http://www.firebase.com.br/fb/artigo.php?id=1107
> Para consultar mensagens antigas: http://firebase.com.br/pesquisa
>
______________________________________________
FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
Para saber como gerenciar/excluir seu cadastro na lista, use:
http://www.firebase.com.br/fb/artigo.php?id=1107
Para consultar mensagens antigas: http://firebase.com.br/pesquisa





Mais detalhes sobre a lista de discussão lista