GARANTIR DESCONTO

Fórum Stored Procedure - Intermediário #38482

02/09/2003

0

Tenho uma tabela de cadastro de PESSOA.

A PESSOA tem um campo CONJUGE que referencia também a tabela de PESSOA.

É uma ´auto-referência´, ou seja lá o que for.

O que quero fazer é:

Quando se informar o código do cônjuge num registro da tabela PESSOA, o registro do cônjuge seja alterado também, para que reflita o código do cônjuge também.

Por favor, ajudem-me.

Obrigado,


Tenil

Tenil

Responder

Posts

02/09/2003

Tenil

Comecei a fazer, por favor, AJUDEM!!!

CREATE PROCEDURE ASSOCIAR_CONJUGE 
AS
begin
     UPDATE pessoa
        SET pessoa.id_conjuge  = pessoa.id_pessoa
        WHERE pessoa.id_pessoa = pessoa.id_pessoa;
  suspend;
end


Valeu,


Responder

Gostei + 0

02/09/2003

Afarias

Uma forma ::


create table pessoas (
id_pessoa integer not null,
nome varchar(10),
id_conjugue integer,
/* outros campos */
primary key (id_pessoa));

alter table pessoas add constraint fk_pessoas1 foreign key (id_conjugue)
references pessoas;

set term ^;

create trigger tr_pessoas_ai for pessoas after insert as
begin
if (new.id_conjugue is not null) then
update pessoas set id_conjugue = new.id_pessoa
where id_pessoa = new.id_conjugue and id_conjugue is null;
end^

set term ;^


T+


Responder

Gostei + 0

03/09/2003

Tenil

Afarias, rolou um problema.

Esse foi o trigger que contruí com a sua dica.
Alterei o momento de execução do Trigger para [b:e9dc64aabd]BEFORE UPDATE[/b:e9dc64aabd]. Isto porque já tenho a tabela povoada.

Só que, pelo que parece, está rolando um loop sem fim. Sempre que se atualiza (UPDATE), o Trigger é executado.

SET TERM ^ ;


CREATE TRIGGER PESSOA_CONJUGE FOR PESSOA
ACTIVE BEFORE UPDATE POSITION 0
AS
begin
  if (new.id_conjuge is not null) then
    update pessoa set id_conjuge = new.id_pessoa
    where id_pessoa = new.id_conjuge and id_conjuge is null;
end

SET TERM ; ^


A seguinte mensagem de erro é mostrada:
Too many concurrent executions of the same request



Responder

Gostei + 0

03/09/2003

Afarias

Sim -- pq neste caso vc não pode usar o BEFORE pois a atualização (da trigger) será na própria tabela -- este tipo de código é meio ´perigoso´ mesmo e tem-se q estar atento aos detalhes::

CREATE TRIGGER PESSOA_CONJUGE FOR PESSOA
ACTIVE AFTER UPDATE POSITION 0 /* <-- mude para AFTER */
AS
begin
if (new.id_conjuge is not null and new.id_conjuge <> old.id_conjugue)
/* tb adicionei o ´and new.id_conjuge <> old.id_conjugue´ só para evitar execuções desnecessárias */
then
update pessoa set id_conjuge = new.id_pessoa
where id_pessoa = new.id_conjuge and id_conjuge is null;
end^


teste este ai!

T+


Responder

Gostei + 0

04/09/2003

Tenil

É brother, não funcionou.

CREATE TRIGGER PESSOA_CONJUGE FOR PESSOA
ACTIVE AFTER UPDATE POSITION 0
AS
begin
    if (new.id_conjuge is not null and new.id_conjuge <> old.id_conjuge) then
        update pessoa set id_conjuge = new.id_pessoa
        where id_pessoa = new.id_conjuge and id_conjuge is null;
end


Não deu erro, mas tb não atulizou o outro registro com o ID_CONJUGE.

O pior é que o código que vc escreveu, ao meu ver, está corretíssimo.

Não quero abusar da sua boa vontade, se vc puder me ajudar ainda mais um pouquinho eu ficarei muito grato.

[]s

Roberto


Responder

Gostei + 0

04/09/2003

Afarias

claro, falha minha, desculpe.

nao levei em conta q, em geral, old.id_conjugue deve ser NULL e sendo assim, nao posso compara-lo a um valor (pois NULL nao e valor)

sendo assim::

old.id_conjugue <> new.id_conjugue vai ser sempre FALSO!

altere a condicao para::

if ((old.id_conjuge is null and new.id_conjugue is not null) or (new.id_conjuge <> old.id_conjuge)) then


Dependendo do caso, vc pode trabalhar em cima desta condicao para definir suas regras particulares,


T+


Responder

Gostei + 0

04/09/2003

Tenil

Mano, [b:dcd7d0f43d]FUNCIONOU[/b:dcd7d0f43d]. :D

Estou colocando o código final aqui, para que você veja que meu desejo é aprender, com a ajuda de todos, e não pegar o código pronto e usá-lo. Outro motivo é: se alguém vier a ter um problema parecido com este, poderá se basear neste exemplo. :wink:

O código final, além de atualizar [b:dcd7d0f43d]vinculando[/b:dcd7d0f43d] os cônjuges, também atualiza [b:dcd7d0f43d]desvinculando[/b:dcd7d0f43d] os mesmos, se for o caso.

Geralmente eu coloco muitos parenteses no código, faço isso para facilitar a compreensão.

CREATE TRIGGER PESSOA_CONJUGE FOR PESSOA
ACTIVE AFTER UPDATE POSITION 0
AS
begin
    if (((old.id_conjuge is null) and (new.id_conjuge is not null)) or (new.id_conjuge <> old.id_conjuge)) then
    begin
        update pessoa set pessoa.id_conjuge = new.id_pessoa
        where pessoa.id_pessoa = new.id_conjuge;
    end
    else if ((new.id_conjuge is null) and (old.id_conjuge is not null)) then
    begin
        update pessoa set pessoa.id_conjuge = null
        where pessoa.id_pessoa = old.id_conjuge;
    end
end


[]s

Roberto


Responder

Gostei + 0

04/09/2003

Afarias

Gostei de ver.... :)

realmente, o q faltava naquele codigo era poder ´desvincular´ -- vc desenvolveu bem o que precisava -- legal ´mano´ !!


Boa sorte.


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar