Usuário com melhor resposta
Ajudar com UPDATE

Pergunta
-
Prezados, bom dia!
Estou com dificuldade em monta sub query para alterar conteúdo.
Essa query
SELECT RH_FILIAL, RH_MAT, CONVERT(VARCHAR(10),CAST(RH_DTRECIB AS DATE), 103), COUNT(RH_MAT)
FROM SRH010
WHERE D_E_L_E_T_ <> '*'
AND RH_DTRECIB <> ' '
GROUP BY RH_FILIAL, RH_MAT, RH_DTRECIB
HAVING COUNT(RH_MAT) > 1
Retornou 491 registro
Com base desses registro preciso efetuar alteração de um determinado campo
Fiz dessa forma
BEGIN TRANSACTION
UPDATE SRH010 SET D_E_L_E_T_ = '*'
WHERE RH_FILIAL = '01' AND RH_MAT IN (SELECT T2.RH_MAT
FROM SRH010 T2
WHERE T2.D_E_L_E_T_ <> '*'
AND T2.RH_DTRECIB <> ' '
GROUP BY T2.RH_FILIAL, T2.RH_MAT, T2.RH_DTRECIB
HAVING COUNT(T2.RH_MAT) > 1)
Alterou em 1500 linhas.
Onde posso esta o erro?
Respostas
-
Rubem,
Provavelmente estão sendo alteradas 1500 linhas devido a algum erro na sua lógica aplicada no Update, o que você poderia fazer é pegar o resultado deste select armazenar os códigos em uma tabela auxiliar e utilizar esta tabela como condição na sua linha do Where no Update.
Outra possibilidade seria utilizar este mesmo select diretamente no Update na claúsula Where em conjunto como operador In para realizar o Update somente com base no retorno do Select.
Veja se o exemplo abaixo ajuda:
UPDATE SRH010 SET D_E_L_E_T_ = '*' WHERE RH_FILIAL In (SELECT RH_FILIAL, COUNT(RH_MAT) FROM SRH010 WHERE D_E_L_E_T_ <> '*' AND RH_DTRECIB <> ' ' GROUP BY RH_FILIAL HAVING COUNT(RH_MAT) > 1)
Não estão validando nem analisando suas regras de negócios, somente estou expondo uma forma que talvez possa ajudar.
Pedro Antonio Galvao Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]
- Marcado como Resposta Filipe B CastroModerator segunda-feira, 20 de novembro de 2017 13:15
Todas as Respostas
-
-
Vejo que na primeira sentença você não filtra pela filial "01", apenas na segunda, fazendo o filtro da primeira sentença apenas para o campo RH_MAT. Então se houver a mesma matrícula para filiais diferentes, você está fazendo o mesmo update mais de uma vez para a mesma matrícula, e se a matrícula da filial "01" não está na situação especificada, mas há uma com mesmo número nessa situação em outra filial, setará o valor de forma equivocada.
Você pode usar CTE e garantir o update nas linhas desejadas de maneira simples:
;WITH UPDATE_DELETE as (SELECT RH_FILIAL, RH_MAT, CAST(RH_DTRECIB AS DATE) DATA FROM SRH010 WHERE D_E_L_E_T_ <> '*' AND RH_FILIAL = '01' AND RH_DTRECIB <> ' ' GROUP BY RH_FILIAL, RH_MAT, CAST(RH_DTRECIB AS DATE) HAVING COUNT(RH_MAT) > 1)
UPDATE UPDATE_DELETE SET D_E_L_E_T_ = '*'
Não seria necessário usar CTE nesse caso, mas a visualização fica bem melhor.
Att,
Antero Marques
_______________________________________________________________________________
Se a resposta for útil, marque como útil, se respondeu totalmente sua dúvida, marque como resposta. O Fórum MSDN é utilizado também como base de conhecimento, então é responsabilidade de todos mantê-lo organizado e funcional.
- Editado Antero Marques segunda-feira, 13 de novembro de 2017 17:25
-
-
Fala Rubem!
No seu select, você está filtrando os registros que possuem duplicidade em filial, matricula e data de recebimento, porém no update você está deletando todos os registros das matriculas que estão em duplicidade, dessa forma a quantidade de linhas afetadas muda.
Outra coisa importante é que sempre que o select tem um group by, o update não irá realizar a alteração com a quantidade exata de retorno do select. justamente pela questão do agrupamento.
Qual a tua intenção nesse update?
Abraço!
"A vida é um paraíso, mas os homens não o sabem e não se preocupam em sabê-lo." Fiodor Dostoievski
-
-
Boa tarde!
Executei e gerou erro
;WITH UPDATE_DELETE as
(SELECT RH_FILIAL, RH_MAT, CAST(RH_DTRECIB AS DATE) DATA
FROM SRH010
WHERE D_E_L_E_T_ <> '*'
AND RH_FILIAL = '01'
AND RH_DTRECIB <> ' '
GROUP BY RH_FILIAL, RH_MAT, CAST(RH_DTRECIB AS DATE)
HAVING COUNT(RH_MAT) > 1)Msg 102, Level 15, State 1, Line 10
Incorrect syntax near ')'.SQL SERVER 2008
-
-
-
Rubem,
você não executou o comando inteiro, faltou justamente o Update. Você apenas carregou a CTE.
Att,
Antero Marques
_______________________________________________________________________________
Se a resposta for útil, marque como útil, se respondeu totalmente sua dúvida, marque como resposta. O Fórum MSDN é utilizado também como base de conhecimento, então é responsabilidade de todos mantê-lo organizado e funcional.- Editado Antero Marques segunda-feira, 13 de novembro de 2017 19:07
-
Rubem,
Provavelmente estão sendo alteradas 1500 linhas devido a algum erro na sua lógica aplicada no Update, o que você poderia fazer é pegar o resultado deste select armazenar os códigos em uma tabela auxiliar e utilizar esta tabela como condição na sua linha do Where no Update.
Outra possibilidade seria utilizar este mesmo select diretamente no Update na claúsula Where em conjunto como operador In para realizar o Update somente com base no retorno do Select.
Veja se o exemplo abaixo ajuda:
UPDATE SRH010 SET D_E_L_E_T_ = '*' WHERE RH_FILIAL In (SELECT RH_FILIAL, COUNT(RH_MAT) FROM SRH010 WHERE D_E_L_E_T_ <> '*' AND RH_DTRECIB <> ' ' GROUP BY RH_FILIAL HAVING COUNT(RH_MAT) > 1)
Não estão validando nem analisando suas regras de negócios, somente estou expondo uma forma que talvez possa ajudar.
Pedro Antonio Galvao Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]
- Marcado como Resposta Filipe B CastroModerator segunda-feira, 20 de novembro de 2017 13:15
-
Vejo que na primeira sentença você não filtra pela filial "01", apenas na segunda, fazendo o filtro da primeira sentença apenas para o campo RH_MAT. Então se houver a mesma matrícula para filiais diferentes, você está fazendo o mesmo update mais de uma vez para a mesma matrícula, e se a matrícula da filial "01" não está na situação especificada, mas há uma com mesmo número nessa situação em outra filial, setará o valor de forma equivocada.
Você pode usar CTE e garantir o update nas linhas desejadas de maneira simples:
;WITH UPDATE_DELETE as (SELECT RH_FILIAL, RH_MAT, CAST(RH_DTRECIB AS DATE) DATA FROM SRH010 WHERE D_E_L_E_T_ <> '*' AND RH_FILIAL = '01' AND RH_DTRECIB <> ' ' GROUP BY RH_FILIAL, RH_MAT, CAST(RH_DTRECIB AS DATE) HAVING COUNT(RH_MAT) > 1)
UPDATE UPDATE_DELETE SET D_E_L_E_T_ = '*'
Não seria necessário usar CTE nesse caso, mas a visualização fica bem melhor.
Att,
Antero Marques
_______________________________________________________________________________
Se a resposta for útil, marque como útil, se respondeu totalmente sua dúvida, marque como resposta. O Fórum MSDN é utilizado também como base de conhecimento, então é responsabilidade de todos mantê-lo organizado e funcional.
Antero,
Concordo com sua sugestão e observação.
Pedro Antonio Galvao Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]
-
Bom dia,
Por falta de retorno essa thread está encerrada.
Se necessário, favor abrir uma nova thread.Atenciosamente,
Filipe B de Castro
Esse conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita
MSDN Community Support
Por favor, lembre-se de Marcar como Resposta as postagens que resolveram o seu problema. Essa é uma maneira comum de reconhecer aqueles que o ajudaram e fazer com que seja mais fácil para os outros visitantes encontrarem a resolução mais tarde.