Página 1 de 2 12 ÚltimoÚltimo
+ Responder ao Tópico



  1. Pessoal,

    Preciso de um ajuda daqueles que entendem de MySQL. Suponham a seguinte estrutura de dados:

    tabela1
    - id
    - nome
    - bloq

    tabela2
    - id
    - nome

    Quero criar um trigger entre as tabelas para que haja uma cópia de algumas linhas baseadas em um critério. Estou me batendo horrores para criar isso. A idéia é a seguinte:

    Quando eu criar, apagar ou modificar uma nova linha na tabela1 que ela passe para a tabela2 entendo alguns critérios. São eles:

    1) Caso INSERT na tabela 1: em caso de inserção de dados na tabela1 então quero que verifique se o campo bloq é N o conteúdo dele então quero que a linha seja copiada para a tabela2.

    2) Caso REMOVE na tabela 1: em caso de remover um nome da tabela 1 então esta mesma linha deve ser removida (com o mesmo nome) da tabela 2.

    3) Caso UPTATE na tabela 1: em caso de fazer uma alteração nas linhas da tabela 1 preciso que seja verificado se o campo BLOQ foi modificado para SIM. Se foi modificado para SIM entao a linha deve ser copiada a tabela 2. Se foi modificado para NAO entao a linha deve ser apagada da tabela 2. Em caso de alteracao do NOME a linha deve ser copiada apenas quando o campo BLOQ estiver em SIM.

    Sei que é perfeitamente possível fazer isso usando TRIGGERS mas não estou conseguindo setar a sintaxe dele. Alguém pode me dar uma mão?

  2. Basicamente os triggers tem o formato de qualquer procedure ou funcao MySQL separados por um delimitador.

    Voce pode criar um trigger antes ou depois das tres operacoes basicas, ou seja, INSERT, UPDATE ou DELETE, um trigger e um bloco de statements executados para cada linha modificada. Ou seja, para vc cria um trigger que vai executar antes de inserir um registro na tabela1 assim:

    CREATE TRIGGER nome_do_trigger BEFORE INSERT ON tabela1
    FOR EACH ROW
    BEGIN
    statement1; .....
    statement2; .....
    statement3; .....
    etc ...
    END;

    Resumindo, vc acessa a linha modificada, a qual vc quer verificar com as palavras-chave OLD ou NEW, dependendo de qual tempo esta executando a acao, ou seja ...

    Trigger no INSERT - So existe o NEW
    Trigger no UPDATE - Existe o OLD e NEW
    Trigger no DELETE - So existe o OLD

    Para integridade dos dados, vale lembrar que vc pode escolher o BEFORE (antes) ou AFTER (depois) da acao. Se vc escolher um trigger antes do UPDATE qualquer erro que ocorrer o UPDATE nao vai ser executado, já se vc escolher depois o UPDATE ja foi executado e se der algum erro, o update, ou insert, etc. já terá sido realizado na tabela1.

    Resumindo, vou fazer o seu primeiro exemplo ... (vou fazer com o AFTER, mas vc pode escolher o BEFORE dependendo da sua necessidade)

    CREATE TRIGGER qualquer_nome AFTER INSERT ON tabela1
    FOR EACH ROW
    BEGIN
    IF NEW.bloq = "N" THEN
    INSERT INTO tabela2 (id, nome) VALUES (NEW.id, NEW.nome);
    END IF;
    END;

    P.S: Lembre-se que quando vc cria um trigger vc tem que mudar o delimitador padrao, porque, vamos dizer no exemplo acima, se deixar o delimitador como ";" o MySQL para de executar o CREATE TRIGGER no INSERT ... Dependendo do programa que usa para executar comandos no MySQL, vc configura o delimitador usando a palavra DELIMITER



  3. Show de bola Marcelo. O IF no quadro me ajudou imensamente... Obrigado. Vou testar aqui e depois mando notícias.

  4. Citação Postado originalmente por marcelocbf Ver Post
    CREATE TRIGGER nome_do_trigger BEFORE INSERT ON tabela1
    FOR EACH ROW
    BEGIN
    statement1; .....
    statement2; .....
    statement3; .....
    etc ...
    END;
    Marcelo,

    Com a sua ajuda eu consegui criar o trigger do modo como eu queria mas estou com um problema ainda. Vou postar o conteúdo como foi criado o triger e sinalizarei onde está o problema:

    Código :
    DELIMITER |
     
    CREATE TRIGGER radius_upd AFTER UPDATE ON radacct_1[INDENT]FOR EACH ROW[/INDENT][INDENT]BEGIN[/INDENT][INDENT][INDENT]IF NEW.AcctStopTime IS NOT NULL THEN[/INDENT][/INDENT][INDENT][INDENT]INSERT INTO radacct (`RadAcctId`, `AcctSessionId`, `AcctUniqueId`, `UserName`, `GroupName`, `Realm`, `NASIPAddress`, `NASPortId`, `NASPortType`, `AcctStartTime`, `AcctStopTime`, `AcctSessionTime`, `AcctAuthentic`, `ConnectInfo_start`, `ConnectInfo_stop`, `AcctInputOctets`, `AcctOutputOctets`, `CalledStationId`, `CallingStationId`, `AcctTerminateCause`, `ServiceType`, `FramedProtocol`, `FramedIPAddress`, `AcctStartDelay`, `AcctStopDelay`, `xascendsessionsvrkey`) VALUES (NEW.RadAcctId, NEW.AcctSessionId, NEW.AcctUniqueId, NEW.UserName, NEW.GroupName, NEW.Realm, NEW.NASIPAddress, NEW.NASPortId, NEW.NASPortType, NEW.AcctStartTime, NEW.AcctStopTime, NEW.AcctSessionTime, NEW.AcctAuthentic, NEW.ConnectInfo_start, NEW.ConnectInfo_stop, NEW.AcctInputOctets, NEW.AcctOutputOctets, NEW.CalledStationId, NEW.CallingStationId, NEW.AcctTerminateCause, NEW.ServiceType, NEW.FramedProtocol, NEW.FramedIPAddress, NEW.AcctStartDelay, NEW.AcctStopDelay, NEW.xascendsessionsvrkey);[/INDENT][/INDENT][INDENT][INDENT][COLOR=Red][B]DELETE FROM radacct_1 WHERE OLD.RadAcctId = NEW.RadAcctId;[/B][/COLOR][/INDENT][/INDENT][INDENT][INDENT]END IF;[/INDENT][/INDENT][INDENT]END;[/INDENT]|
     
    DELIMITER ;
    A primeira linha que copia os dados da tabela que está recebendo o UPDATE está perfeita e copiando mas depois de copiados os dados quero que a tabela inicial suma com a linha que terá conteúdo na coluna AcctStopTime. Já tentei 1001 peripécias mas até o momento não consegui.

    Se puderes me ajudar novamente, neste comando de DELETE eu agradeço imensamente.



  5. Citação Postado originalmente por nataniel Ver Post
    DELETE FROM radacct_1 WHERE OLD.RadAcctId = NEW.RadAcctId;
    Eu ia perguntar se isso gerava algum erro na engine do MySQL, mas creio que não chega a gerar pois ele não deve encontrar nada pra deletar, e sinceramente acho que ele não vai te deixar executar uma outra operação no row com a operação atual não-"oficialmente" terminada, mas vc pode tentar para ver realmente se não ...
    O que acontece com o statement acima é que quando vc diz "WHERE OLD.RadAcctId" vc está referenciando um valor e não a coluna RadAcctId, o certo seria vc pôr ... DELETE FROM radacct_1 WHERE RadAcctId = NEW.RadAcctId;

    Poderia te dar uma sugestão que também tenho 99,9% de certeza que ele não vai te deixar executar que seria criar um trigger no INSERT na tabela radacct para DELETE FROM radacct_1 WHERE RadAcctId = NEW.RadAcctId AND AccStopTime IS NOT NULL, pois acho que apesar de estar "oficialmente" em operações diferentes a primeira row ainda vai estar locked, mas como a primeira operação é um UPDATE vc pode tentar ... Eu sou tipo Tomé, só acredito que não dá certo, quando vejo o erro, rs ...

    Ou vc poderia criar um campo na tabela radacct_1 para sinalizar que aquele registro seria um candidato à deleção e à sua conveniência passar um script de deleção nesses registros ... mas acho que essa segunda opção não é tão elegante ...

    Falow,

    Feliz Ano Novo ...






Tópicos Similares

  1. Trigger Mysql pegando qualquer registro.
    Por fernandochina no fórum Servidores de Rede
    Respostas: 0
    Último Post: 09-03-2012, 09:37
  2. Mysql criar trigger mais de um produto
    Por ribeiro3001 no fórum Servidores de Rede
    Respostas: 3
    Último Post: 12-08-2010, 12:03
  3. TRIGGER MySQL
    Por Bituim no fórum Servidores de Rede
    Respostas: 1
    Último Post: 21-04-2006, 14:45
  4. Mysql suporta triggers?
    Por Romulo Neves no fórum Servidores de Rede
    Respostas: 10
    Último Post: 24-05-2004, 11:59
  5. configurando o mysql
    Por no fórum Servidores de Rede
    Respostas: 2
    Último Post: 28-03-2002, 10:52

Visite: BR-Linux ·  VivaOLinux ·  Dicas-L