Update no campo com valor de outra tabela com JOIN

Oracle PL SQL

08/07/2019

Boa tarde!

Preciso fazer um Update em um campo de uma tabela. Só que precisa trazer valores de outra tabel para esse campo.

Tenho três tabelas envolvidas
SELECT * FROM PRODUTO
WHERE CD_PRODUTO = 128
cd_produto = 128
cd_especie = 1 (drogas e medicamentos)

SELECT * FROM UNI_PRO
WHERE CD_PRODUTO = 128
Cd_produto = 128|Cd_uni_pro = 238 |cd_uni_pro = UN |cd_unidade = UNIDADE
d_produto = 128 | cd_uni_pro = 239 |cd_uni_pro = MG |cd_unidade = COMP C/25MG


SELECT * FROM IDENTIFICADOR_ETIQUETA
WHERE CD_PRODUTO = 128
CD_IDENTICADOR = 365 | CD_PRODUTO = 128 | CD_UNI_PRO = 239

Eu preciso alterar na tabela IDENTIFICADOR_ETIQUETA, o CD_UNI_PRO que está com a unidade incorreta de acordo com a tabela UNI_PRO. O certo é 238 = Unidade, Detahe que eu preciso alterar para todos os produtos da Tabel identificador_etiqueta.

Montei dois Updates amarrando somente um único código para teste.

UPDATE IDENTIFICADOR_ETIQUETA SET CD_UNI_PRO =CD_UNI_PRO
WHERE CD_UNI_PRO IN (SELECT UNI_PRO.CD_UNI_PRO FROM UNI_PRO
JOIN PRODUTO ON PRODUTO.CD_PRODUTO = UNI_PRO.CD_PRODUTO
WHERE PRODUTO.CD_ESPECIE = ''''''''1''''''''
AND UNI_PRO.CD_UNIDADE = ''''''''UN''''''''
AND UNI_PRO.SN_ATIVO = ''''''''S''''''''
AND PRODUTO.CD_PRODUTO = 128)
AND IDENTIFICADOR_ETIQUETA.CD_PRODUTO = 128

Diz Text
Update - 0 row(s), executed in 15 ms
Total execution time 31 ms

OU
UPDATE IDENTIFICADOR_ETIQUETA
SET CD_UNI_PRO = (SELECT UNI_PRO.CD_UNI_PRO FROM UNI_PRO
JOIN PRODUTO ON PRODUTO.CD_PRODUTO = UNI_PRO.CD_PRODUTO
WHERE PRODUTO.CD_ESPECIE = ''''''''1''''''''
AND UNI_PRO.CD_UNIDADE = ''''''''UN''''''''
AND UNI_PRO.SN_ATIVO = ''''''''S''''''''
AND PRODUTO.CD_PRODUTO IN (128)
AND ROWNUM= 1)
WHERE IDENTIFICADOR_ETIQUETA.CD_PRODUTO IN (128) -- Dessa forma, funciona. Quando insiro, mais itens, ele pega um UNI_PRO único e replica para vários.
Paula Barbosa

Paula Barbosa

Curtidas 0

Melhor post

Emerson Nascimento

Emerson Nascimento

11/07/2019

deve ser algo assim:
UPDATE IDETIQ SET IDETIQ.CD_UNI_PRO = UPRO.CD_UNI_PRO
FROM IDENTIFICADOR_ETIQUETA IDETIQ
INNER JOIN UNI_PRO UPRO ON UPRO.CD_PRODUTO = IDETIQ.CD_PRODUTO
	AND UPRO.SN_ATIVO = 'S'
	AND UPRO.CD_UNIDADE = 'UN'
INNER JOIN PRODUTO P ON P.CD_PRODUTO = UPRO.CD_PRODUTO
	AND P.CD_ESPECIE = '1'
WHERE IDETIQ.CD_PRODUTO IN (128)

Na verdade basta você montar a instrução (select) que retorne os dados como você precisa, e depois trocar o select por update.
GOSTEI 1

Mais Respostas

Sérgio Saibel

Sérgio Saibel

08/07/2019

Bom dia....

Não sei se entendi direito, mas vê se isso resolve teu problema...

<SQL>
UPDATE IDENTIFICADOR_ETIQUETA SET CD_UNI_PRO =
(SELECT UNI_PRO.CD_UNI_PRO
FROM UNI_PRO
JOIN PRODUTO ON PRODUTO.CD_PRODUTO = UNI_PRO.CD_PRODUTO
WHERE PRODUTO.CD_ESPECIE = ''''''''1''''''''
AND UNI_PRO.CD_UNIDADE = ''''''''UN''''''''
AND UNI_PRO.SN_ATIVO = ''''''''S''''''''
AND PRODUTO.CD_PRODUTO = 128)
WHERE IDENTIFICADOR_ETIQUETA.CD_PRODUTO = 128
</SQL>

Se a sua amarração de tabelas estiver correta acho que isso resolve o problema.

Abraço
GOSTEI 0
Paula Barbosa

Paula Barbosa

08/07/2019

Bom dia....

Não sei se entendi direito, mas vê se isso resolve teu problema...

<SQL>
UPDATE IDENTIFICADOR_ETIQUETA SET CD_UNI_PRO =
(SELECT UNI_PRO.CD_UNI_PRO
FROM UNI_PRO
JOIN PRODUTO ON PRODUTO.CD_PRODUTO = UNI_PRO.CD_PRODUTO
WHERE PRODUTO.CD_ESPECIE = ''''''''1''''''''
AND UNI_PRO.CD_UNIDADE = ''''''''UN''''''''
AND UNI_PRO.SN_ATIVO = ''''''''S''''''''
AND PRODUTO.CD_PRODUTO = 128)
WHERE IDENTIFICADOR_ETIQUETA.CD_PRODUTO = 128
</SQL>

Se a sua amarração de tabelas estiver correta acho que isso resolve o problema.
______________________________________________________||_______________________________________________
Sérgio, bom dia!

Obrigada pelo retorno. O problema é que tenho + de 1 codigo específico dentro da tabela produto que está presente na tabela identificador de etiquetas. Se eu fizer dessa forma que informou, o código roda somente para 1 item. Se eu colocar mais itens. Ele me traz erro. Exemplo:

UPDATE IDENTIFICADOR_ETIQUETA SET CD_UNI_PRO =
(SELECT UNI_PRO.CD_UNI_PRO
FROM UNI_PRO
JOIN PRODUTO ON PRODUTO.CD_PRODUTO = UNI_PRO.CD_PRODUTO
WHERE PRODUTO.CD_ESPECIE = 1
AND UNI_PRO.CD_UNIDADE = 'UN'
AND UNI_PRO.SN_ATIVO = 'S'
AND PRODUTO.CD_PRODUTO IN (7,
8 ,
9 ,
12,
13,
14,
15,
16,
17,
19,
20,
21,
22))
WHERE IDENTIFICADOR_ETIQUETA.CD_PRODUTO IN (7,
8,
9,
12,
13,
14,
15,
16,
17,
19,
20,
21,
22)

Erro: ORA-01427: a subconsulta de uma única linha retorna mais de uma linha.
Por isso, tinha colocado o RowNum, pois ele meio que burla essa mensagem. Só que, ele pega o valor UNI_PRO.CD_PRODUTO e replica para o restante dos códigos.


GOSTEI 0
Sérgio Saibel

Sérgio Saibel

08/07/2019

Bom dia....

Não sei se entendi direito, mas vê se isso resolve teu problema...

<SQL>
UPDATE IDENTIFICADOR_ETIQUETA SET CD_UNI_PRO =
(SELECT UNI_PRO.CD_UNI_PRO
FROM UNI_PRO
JOIN PRODUTO ON PRODUTO.CD_PRODUTO = UNI_PRO.CD_PRODUTO
WHERE PRODUTO.CD_ESPECIE = ''''''''''''''''1''''''''''''''''
AND UNI_PRO.CD_UNIDADE = ''''''''''''''''UN''''''''''''''''
AND UNI_PRO.SN_ATIVO = ''''''''''''''''S''''''''''''''''
AND PRODUTO.CD_PRODUTO = 128)
WHERE IDENTIFICADOR_ETIQUETA.CD_PRODUTO = 128
</SQL>

Se a sua amarração de tabelas estiver correta acho que isso resolve o problema.
______________________________________________________||_______________________________________________
Sérgio, bom dia!

Obrigada pelo retorno. O problema é que tenho + de 1 codigo específico dentro da tabela produto que está presente na tabela identificador de etiquetas. Se eu fizer dessa forma que informou, o código roda somente para 1 item. Se eu colocar mais itens. Ele me traz erro. Exemplo:

UPDATE IDENTIFICADOR_ETIQUETA SET CD_UNI_PRO =
(SELECT UNI_PRO.CD_UNI_PRO
FROM UNI_PRO
JOIN PRODUTO ON PRODUTO.CD_PRODUTO = UNI_PRO.CD_PRODUTO
WHERE PRODUTO.CD_ESPECIE = 1
AND UNI_PRO.CD_UNIDADE = ''UN''
AND UNI_PRO.SN_ATIVO = ''S''
AND PRODUTO.CD_PRODUTO IN (7,
8 ,
9 ,
12,
13,
14,
15,
16,
17,
19,
20,
21,
22))
WHERE IDENTIFICADOR_ETIQUETA.CD_PRODUTO IN (7,
8,
9,
12,
13,
14,
15,
16,
17,
19,
20,
21,
22)

Erro: ORA-01427: a subconsulta de uma única linha retorna mais de uma linha.
Por isso, tinha colocado o RowNum, pois ele meio que burla essa mensagem. Só que, ele pega o valor UNI_PRO.CD_PRODUTO e replica para o restante dos códigos.




Beleza...
Só que o que estas tentando fazer não pode ser feito desta forma. O update somente altera um CD_PRODUTO por vez. Se tens mais de um código a ser alterado e o valor for o mesmo então retira da cláusula, do primeiro WHERE ...
<SQL>
WHERE PRODUTO.CD_ESPECIE = 1
AND UNI_PRO.CD_UNIDADE = ''UN''
AND UNI_PRO.SN_ATIVO = ''S''
</SQL>

Se para cada código de produto for um valor diferente então sugiro criar uma função do tipo:

<SQL>
CREATE OR REPLACE FUNCTION __atualizar_etiqueta()
RETURNS INTEGER AS $__atualizar_etiqueta$
DECLARE
rx RECORD;
v_rows INTEGER;
BEGIN
FOR rx IN (SELECT PRODUTO.CD_PRODUTO , UNI_PRO.CD_UNI_PRO FROM UNI_PRO JOIN PRODUTO ON PRODUTO.CD_PRODUTO = UNI_PRO.CD_PRODUTO WHERE PRODUTO.CD_ESPECIE = 1 AND UNI_PRO.CD_UNIDADE = ''UN'' AND UNI_PRO.SN_ATIVO = ''S'' AND PRODUTO.CD_PRODUTO IN (7, 8 ,9 ,12,13,14,15,16,17,19,20,21,22) LOOP
BEGIN
-- Altera os valores do código com base nos valores da tabela 2
UPDATE IDENTIFICADOR_ETIQUETA SET CD_UNI_PRO = rx.CD_UNI_PRO
WHERE IDENTIFICADOR_ETIQUETA.CD_PRODUTO = rx.CD_PRODUTO ;
END;
END LOOP;

RETURN row_count;;
END;
$__atualizar_etiqueta$ LANGUAGE plpgsql;
</SQL>

Mais ou menos isso, para executar

SELECT __atualizar_etiqueta;

Espero ter ajudado, tenta e posta o resultado. Abraço
GOSTEI 0
POSTAR