Ajuda com update usando filtros de outra tabela

Dúvidas, dicas e truques de SQL, Select, Update, Delete, cláusulas, operações com joins, Funções em SQLs, etc
ThiagolRamos
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 19
Registrado em: Ter, 03 Nov 2015 9:53 am

Boa noite pessoal,

Estou com uma dúvida que talvez seja simples, mas não sou muito bom em SQL e acabou surgindo uma necessidade que preciso resolver via banco.

Há alguns registros que devo alterar, porém para encontra-los utilizo filtros de 2 tabelas, vou usar de exemplo a tabela A e tabela B, o select faço dessa forma:

Selecionar tudo

SELECT * FROM A, B
       WHERE A.FILIAL = B.FILIAL
                AND A.FORNECEDOR = B.FORNECEDOR 
                AND A.DATAENTRADA > '31/12/2011' 
                AND A.DATAENTRADA < '01/01/2014'
                AND B.CSTPIS = '53'
                AND B.CSTCOFINS = '53'
                AND B.VALORPIS > 0
                AND B.VALORCOFINS > 0
                AND A.CODESP = '27'
Ele me traz 841 registros, eu preciso alterar o campo CODESP para '0', se eu faço com FOR UPDATE no fim e tento alterar manualmente um a um na tabela, ele me retorna um erro de ROWID INVÁLIDO.

Tentei fazer dessa forma e não deu certo:

Selecionar tudo

UPDATE A SET A.CODESP = (SELECT 0 FROM A, B
       WHERE A.FILIAL = B.FILIAL
                AND A.FORNECEDOR = B.FORNECEDOR 
                AND A.DATAENTRADA > '31/12/2011' 
                AND A.DATAENTRADA < '01/01/2014'
                AND B.CSTPIS = '53'
                AND B.CSTCOFINS = '53'
                AND B.VALORPIS > 0
                AND B.VALORCOFINS > 0
                AND A.CODESP = '27')
Mas ele retorna um erro pelo que parece que estou tentando colocar mais de 1 resultado por linha do update.

Alguém tem ideia de como posso fazer esse código.

Desde já, agradeço pela ajuda.
Avatar do usuário
tiago_pimenta
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 213
Registrado em: Qua, 29 Jun 2011 9:49 am
Localização: Barretos / SP

Tenta se assim dá certo...

Selecionar tudo

update a
set a.codesp = (select 0
                from b
                where b.filial = a.filial
                  and b.fornecedor = a.fornecedor
                  and a.dataentrada > '31/12/2011'
                  and a.dataentrada < '01/01/2014'
                  and b.cstpis = '53'
                  and b.cstcofins = '53'
                  and b.valorpis > 0
                  and b.valorcofins > 0
                  and a.codesp = '27')
ThiagolRamos
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 19
Registrado em: Ter, 03 Nov 2015 9:53 am

Bom dia,

Ele apresentou uma mensagem de erro:

Selecionar tudo

ORA-01407: não é possível atualizar ("NOMEDAINSTANCIA"."A"."CODESP") para NULL
Avatar do usuário
tiago_pimenta
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 213
Registrado em: Qua, 29 Jun 2011 9:49 am
Localização: Barretos / SP

Roda o select interno e veja o que retorna !!! Provavelmente o select interno está retornando NULL e o campo no qual você está atualizando não aceita NULL
ThiagolRamos
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 19
Registrado em: Ter, 03 Nov 2015 9:53 am

Então, quando rodo o SELECT da forma que coloquei primeiro ele trás os resultados:

Selecionar tudo

SELECT 0 FROM A, B
       WHERE A.FILIAL = B.FILIAL
                AND A.FORNECEDOR = B.FORNECEDOR 
                AND A.DATAENTRADA > '31/12/2011' 
                AND A.DATAENTRADA < '01/01/2014'
                AND B.CSTPIS = '53'
                AND B.CSTCOFINS = '53'
                AND B.VALORPIS > 0
                AND B.VALORCOFINS > 0
                AND A.CODESP = '27'

Quando rodo da que você indicou:

Selecionar tudo

select 0
                from b
                where b.filial = a.filial
                  and b.fornecedor = a.fornecedor
                  and a.dataentrada > '31/12/2011'
                  and a.dataentrada < '01/01/2014'
                  and b.cstpis = '53'
                  and b.cstcofins = '53'
                  and b.valorpis > 0
                  and b.valorcofins > 0
                  and a.codesp = '27'
Ele não retorna nada, acredito que seja porque o FROM está referenciando só a tabela B, ai ele diz que o a.codesp não existe.
Avatar do usuário
tiago_pimenta
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 213
Registrado em: Qua, 29 Jun 2011 9:49 am
Localização: Barretos / SP

ThiagolRamos
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 19
Registrado em: Ter, 03 Nov 2015 9:53 am

Boa tarde,

Acho que descobri o motivo do erro, mas ainda não a solução.

O select está trazendo mais de um resultado pois na tabela B que é a tabela de itens da nota, há mais de um item para cada registro da tabela A

Então ele traz por exemplo FORNECEDOR = 55 e NUMERO DA NOTA = 10 mas traz 3 registros desses.
Avatar do usuário
tiago_pimenta
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 213
Registrado em: Qua, 29 Jun 2011 9:49 am
Localização: Barretos / SP

Bom, acredito que você tenha duas soluções...

- Ver se não está faltando mas nenhum campo na "amarração";
- Colocar um distinct no select interno.
ThiagolRamos
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 19
Registrado em: Ter, 03 Nov 2015 9:53 am

Bom dia, pensei no distinct, mas fiquei com uma dúvida.

Ele é utilizado em apenas 1 campo, certo? Então se eu usasse no campo que tem o número da nota, ok, ele me traria apenas 1 registro para cada número de nota.

Mas se eu tiver 2 notas com o mesmo número, mas de fornecedores diferentes, ele trará apenas 1 registro ou ele fara a distinção dos dois por ter fornecedores diferentes?
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante