Logo Hardware.com.br
Felipe Nicolodi
Felipe Nicol... Novo Membro Registrado
10 Mensagens 0 Curtidas

Atualizar campo com base em outra tabela

#1 Por Felipe Nicol... 16/09/2015 - 14:48
Boa tarde,

Tenho conhecimento básico em sql e estou com a seguinte dúvida:

Tenho a tabela "Produto" e preciso criar uma outra tabela onde vou ter esses mesmos produtos (código e descrição) para uma outra finalidade... Como eu faço para que se a descrição (ou o código) do produto x em "Produto" mudar, também mude automaticamente nessa outra tabela?

Exemplo:

"Produto"
O 'Cod: 1 Descricao: x' foi alterado para 'Cod: 1 Descricao: y', então na outra tabela também mudará para 'Cod: 1 Descricao: y'.

É possível?
Shinayder
Shinayder Veterano Registrado
669 Mensagens 118 Curtidas
#2 Por Shinayder
17/09/2015 - 08:02
Falipé, normalmente o ID é PK, voce nao conseguiria muda-lo.

você pode criar uma procedure e fazer com que ela seja chamado pro algum sistemas e executada conforme seu desejo

[CODE=SQL]If (p.descricao <> pr.descricao) then
update fat.produto pr
set pr.descricao = (select p.descricao from tab.produto p where p.id_produto = 1)
where pr.id_produto = p.id_produto[/CODE]
Phenon X4 Black Box Edition 3.4 64bits | Memoria DDR3 8Gb | Nvidea Geforce GTS 450 1GB| HD Samsung SATA 500Gb e Samsung SATA 1 Tb rindo_atoa.gif
NoteBook: Em Analise nao_sei.gif
http://www.stormclouds.com.br/
TerraSkilll
TerraSkilll Zumbi Moderador
4K Mensagens 1.2K Curtidas
#3 Por TerraSkilll
17/09/2015 - 09:21
Shinayder disse:
Falipé, normalmente o ID é PK, voce nao conseguiria muda-lo.

você pode criar uma procedure e fazer com que ela seja chamado pro algum sistemas e executada conforme seu desejo

[CODE=SQL]If (p.descricao <> pr.descricao) then
update fat.produto pr
set pr.descricao = (select p.descricao from tab.produto p where p.id_produto = 1)
where pr.id_produto = p.id_produto[/CODE]


Melhor ainda, faça uma trigger na tabela original que é disparada sempre que houver uma alteração. Assim, qualquer update na tabela original será automaticamente refletida na tabela cópia. E, como comentado pelo Shinayder, se o código é a chave primária, ele não pode ser alterado, pois ele é a referência única desse registros nas demais tabelas.

A sintaxe do da trigger seria similar ao postado pelo Shinayder para a procedure. Mas alguns detalhes dependem de qual banco de dados você está usando.

Abraço.
Contribua para um fórum melhor: pense antes de postar.
"It isn't a contest. Just enjoy the ride." -> Seth Vidal
Hardware.com.br no Youtube!
Felipe Nicolodi
Felipe Nicol... Novo Membro Registrado
10 Mensagens 0 Curtidas
#4 Por Felipe Nicol...
17/09/2015 - 10:58
TerraSkilll disse:
Melhor ainda, faça uma trigger na tabela original que é disparada sempre que houver uma alteração. Assim, qualquer update na tabela original será automaticamente refletida na tabela cópia. E, como comentado pelo Shinayder, se o código é a chave primária, ele não pode ser alterado, pois ele é a referência única desse registros nas demais tabelas.

A sintaxe do da trigger seria similar ao postado pelo Shinayder para a procedure. Mas alguns detalhes dependem de qual banco de dados você está usando.

Abraço.


Shinayder e TerraSkilll, obrigado pelas dicas, já esclareceram boa parte da minha dúvida. Quanto ao Banco de Dados, é Oracle.

Eu nunca criei uma Trigger, vocês poderiam me ajudar com isso? Em como seria a sintaxe dela neste caso.
Shinayder
Shinayder Veterano Registrado
669 Mensagens 118 Curtidas
#5 Por Shinayder
17/09/2015 - 11:09
Felipe,

desculpe errar seu nome antes, segue exemplo.

[CODE=SQL]create or replace trigger fat.produtos is

before insert or delete or update on produtos
referencing new as new old as old

begin
if (p.descricao <> pr.descricao) then
update fat.produto pr
set pr.descricao =
(select p.descricao from tab.produto p where p.id_produto = 1)
where pr.id_produto = p.id_produto;
commit;
end if;
end;[/CODE]
Phenon X4 Black Box Edition 3.4 64bits | Memoria DDR3 8Gb | Nvidea Geforce GTS 450 1GB| HD Samsung SATA 500Gb e Samsung SATA 1 Tb rindo_atoa.gif
NoteBook: Em Analise nao_sei.gif
http://www.stormclouds.com.br/
Felipe Nicolodi
Felipe Nicol... Novo Membro Registrado
10 Mensagens 0 Curtidas
#6 Por Felipe Nicol...
17/09/2015 - 11:31
Shinayder disse:
Felipe,

desculpe errar seu nome antes, segue exemplo.

[CODE=SQL]create or replace trigger fat.produtos is

before insert or delete or update on produtos
referencing new as new old as old

begin
if (p.descricao <> pr.descricao) then
update fat.produto pr
set pr.descricao =
(select p.descricao from tab.produto p where p.id_produto = 1)
where pr.id_produto = p.id_produto;
commit;
end if;
end;[/CODE]


Sem problemas Shinayder, muito obrigado pela ajuda.

Na linha: (select p.descricao from tab.produto p where p.id_produto = 1), eu não entendi porque esse "where p.id_produto = 1", eu não poderia simplesmente colocar a linha de baixo "where pr.id_produto = p.id_produto" dentro desse parenteses? Assim ele verificaria todos os produtos e atualizaria todos os que estivessem diferentes, correto?
Shinayder
Shinayder Veterano Registrado
669 Mensagens 118 Curtidas
#7 Por Shinayder
17/09/2015 - 13:21
Felipe, Perceba que no Select eu dou a referencia de um ID, lembra-se do que o @TerraSkilll disse, que os ID's são Chaves Primarias, e que sempre vão ser as mesma, Ou pelo menos quase sempre? Elas não mudam, ali foi só um exemplo, para você ver as diferenças, eu já efetuei um If la em cima, então, se as Descrições forem divergentes, ele executa o update, no Select, eu coloquei o Where por costume, mas voce pode descarta-lo fazendo com que o select traga todos os campos da coluna descrição.

Ex
[CODE=SQL]
SELECT p.descricao FROM tab.produto p
[/CODE]

Assim ele trara todos os campos e não mais apenas a Descrição do ID = 1
Phenon X4 Black Box Edition 3.4 64bits | Memoria DDR3 8Gb | Nvidea Geforce GTS 450 1GB| HD Samsung SATA 500Gb e Samsung SATA 1 Tb rindo_atoa.gif
NoteBook: Em Analise nao_sei.gif
http://www.stormclouds.com.br/
Felipe Nicolodi
Felipe Nicol... Novo Membro Registrado
10 Mensagens 0 Curtidas
#8 Por Felipe Nicol...
17/09/2015 - 13:35
Eu tentei criar conforme você mostrou no exemplo, porém ele deu erro, o primeiro foi no "IS", apareceu: missing BEFORE, AFTER or INSTEAD OF keyword , então eu tirei o IS, daí ficou dessa forma:

CREATE OR REPLACE TRIGGER modarc.TRG_PLANODEMETAS_PRODUTOS
BEFORE INSERT OR UPDATE
ON produto
REFERENCING NEW AS NEW OLD AS OLD

BEGIN
IF (p.descricao <> pl.descricao) THEN

update planodemetas_bkp pl
set pl.descricao = (select p.descricao from produto p)
where pl.codprod = p.codprod;
commit;
END IF;
END;

E apareceu o erro: ORA-24344: success with compilation error2/10 PLS-00201: identifier 'P.DESCRICAO' must be declared2/5 PL/SQL: Statement ignored.

Pelo que eu entendi, vou ter que declarar esses campos? Como faço isso? No resto, eu fiz correto?
TerraSkilll
TerraSkilll Zumbi Moderador
4K Mensagens 1.2K Curtidas
#9 Por TerraSkilll
17/09/2015 - 13:39
Felipe Nicolodi disse:
Sem problemas Shinayder, muito obrigado pela ajuda.

Na linha: (select p.descricao from tab.produto p where p.id_produto = 1), eu não entendi porque esse "where p.id_produto = 1", eu não poderia simplesmente colocar a linha de baixo "where pr.id_produto = p.id_produto" dentro desse parenteses? Assim ele verificaria todos os produtos e atualizaria todos os que estivessem diferentes, correto?


Opa, acredito que foi um pequeno deslize do Shinayder. Sim, a ideia é usar o id como referência para atualizar a tabela de cópia. Mas a comparação pode ser feita já com base no registro que está sendo inserido, que, durante a execução da trigger, sabe quais eram os valores anteriores e atualizados. Algo como:

CREATE OR REPLACE TRIGGER fat.atualiza_produtos_copia IS

BEFORE UPDATE ON produtos_original
REFERENCING NEW AS NEW OLD AS OLD

BEGIN
IF(NEW.descricao <> OLD.descricao)THEN
UPDATE fat.produtos_copia pr
SET pr.descricao = NEW.descricao
WHERE pr.id_produto = NEW.id_produto;
commit;
ENDIF;
END;


As variáveis old e new armazenam o estado do registro antes e depois da alteração, ou seja, old.descricao contém a descrição anterior, e new.descricao contém a descrição atualizada.

Perceba que coloquei a trigger somente no On Update. Isso porque no On Delete, você não precisaria alterar a descrição e sim excluir o registro correspondente na tabela produtos_copia. E no On Insert, você precisaria inserir um registro. Isso seriam triggers diferentes (ou uma adaptação dessa trigger).

Obs: não testei a sintaxe, pode haver alguma coisa errada.

Abraços.
Contribua para um fórum melhor: pense antes de postar.
"It isn't a contest. Just enjoy the ride." -> Seth Vidal
Hardware.com.br no Youtube!
Felipe Nicolodi
Felipe Nicol... Novo Membro Registrado
10 Mensagens 0 Curtidas
#10 Por Felipe Nicol...
17/09/2015 - 13:46
TerraSkilll disse:
Opa, acredito que foi um pequeno deslize do Shinayder. Sim, a ideia é usar o id como referência para atualizar a tabela de cópia. Mas a comparação pode ser feita já com base no registro que está sendo inserido, que, durante a execução da trigger, sabe quais eram os valores anteriores e atualizados. Algo como:

CREATE OR REPLACE TRIGGER fat.atualiza_produtos_copia IS

BEFORE UPDATE ON produtos_original
REFERENCING NEW AS NEW OLD AS OLD

BEGIN
IF(NEW.descricao <> OLD.descricao)THEN
UPDATE fat.produtos_copia pr
SET pr.descricao = NEW.descricao
WHERE pr.id_produto = NEW.id_produto;
commit;
ENDIF;
END;


As variáveis old e new armazenam o estado do registro antes e depois da alteração, ou seja, old.descricao contém a descrição anterior, e new.descricao contém a descrição atualizada.

Perceba que coloquei a trigger somente no On Update. Isso porque no On Delete, você não precisaria alterar a descrição e sim excluir o registro correspondente na tabela produtos_copia. E no On Insert, você precisaria inserir um registro. Isso seriam triggers diferentes (ou uma adaptação dessa trigger).

Obs: não testei a sintaxe, pode haver alguma coisa errada.

Abraços.


TerraSkilll, tentei fazer igual você mostrou e apareceu praticamente o mesmo erro:

ORA-24344: success with compilation error2/7 PLS-00201: identifier 'NEW.DESCRICAO' must be declared2/1 PL/SQL: Statement ignored.

O que devo fazer?
TerraSkilll
TerraSkilll Zumbi Moderador
4K Mensagens 1.2K Curtidas
#11 Por TerraSkilll
17/09/2015 - 13:53
Como disse, não chequei a sintaxe. Dê uma pesquisada na sintaxe de triggers e em como usar old e new dentro delas. Minha ideia era mostrar como o código poderia ser estruturado. Provavelmente no Oracle haja algumas particularidades.

Abraço.
Contribua para um fórum melhor: pense antes de postar.
"It isn't a contest. Just enjoy the ride." -> Seth Vidal
Hardware.com.br no Youtube!
Felipe Nicolodi
Felipe Nicol... Novo Membro Registrado
10 Mensagens 0 Curtidas
#12 Por Felipe Nicol...
17/09/2015 - 13:56
TerraSkilll disse:
Como disse, não chequei a sintaxe. Dê uma pesquisada na sintaxe de triggers e em como usar old e new dentro delas. Minha ideia era mostrar como o código poderia ser estruturado. Provavelmente no Oracle haja algumas particularidades.

Abraço.


Certo, eu já estou lendo uns links pra ver se consigo resolver, pelo que entendi tenho que declarar isso antes, assim que eu conseguir posto aqui.
© 1999-2024 Hardware.com.br. Todos os direitos reservados.
Imagem do Modal