Se Existir – Selecione Código de Prevenção de Repetição

Recebemos uma lista de pedidos e a validamos começa com certos prefixos, por exemplo, se OrderNumber não começar com ABC, então exiba lista de pedidos para o usuário como erro. Usamos existe, para pesquisar a primeira existência, não queremos consumir muito tempo de desempenho. Se não existir, podemos começar a realizar outra tarefa no código.

Existe alguma maneira no sql para se livrar o código repetitivo? Temos muitas verificações como essa em várias tabelas, tentando tornar o código mais eficiente.

if exists ( select * from dbo.OrdersImport where left(OrderNumber,3) <> "ABC" ) begin select OrderNumber as OrderErrorList from dbo.OrdersImport where left(OrderNumber,3) <> "ABC" end else 

Resposta

Infelizmente, temo que, ao tentar evitar a repetição do código, você possa acabar escrevendo mais código e tornando a consulta menos legível. Mas creio que isso pode ser vantajoso para você – leve em consideração as situações em que no teste você só teria que pesquisar em uma ou duas tabelas, onde para recuperar todos os detalhes você terá que juntar a várias outras. Nessas situações, você pode simplificar a consulta de teste, tornando-os mais rápidos de executar.

E enquanto estamos nisso, você também pode considerar alterar sua instrução WHERE. Usar funções no predicado torna não SARGable e evita o uso de índices nesses casos. Uma abordagem melhor neste exemplo seria verificar

WHERE OrderNumber LIKE "ABC%" 

, pois o otimizador realizará a conversão para algo semelhante a

OrderNumber >= "ABC" AND OrderNumber < "ABD" 

que suporta o uso de índices. Portanto, seria Index Scan (usando left ()) versus Index Seek (usando LIKE).

Resposta

Infelizmente, para uma variedade de razões (não apenas legado) SQL não tem quase todas as opções de reutilização de código e recursos que a maioria das linguagens de cliente tem e alguns deles (como UDFs escalares) têm problemas significativos. Portanto, em grande parte, se você deseja ser um programador de SQL eficaz, precisa se resignar a fazer muito mais recortar e colar a reutilização de código do que você jamais consideraria em uma linguagem cliente como C #, VB. Net ou Java.

Dito isso, você pode eliminar a redundância em seu exemplo, no entanto, se é realmente melhor ou não, você “terá que decidir.

Declare @OrderErrorList Table(OrderNumber varchar(32)); Insert into @OrderErrorList select OrderNumber as OrderErrorList from dbo.OrdersImport where left(OrderNumber,3) <> "ABC"; if exists ( select * from @OrderErrorList ) begin select * from @OrderErrorList end else 

Comentários

  • Você poderia simplificar ainda mais marcando @@ ROWCOUNT em vez de existe?
  • @mathewb Sim, mas deve ser feito imediatamente após o INSERT..SELECT. Se você adicionar outra afirmação, de repente ela para de funcionar corretamente e tento evitar minas terrestres como essa em minhas respostas. A solução alternativa seria salvar @@ ROWCOUNT em uma variável, mas não seria significativamente melhor do que o que eu tenho acima.

Resposta

Existe alguma maneira no sql para se livrar do código repetitivo?

Na verdade não. Você pode reformular a consulta assim, sem a instrução IF, mas não é realmente diferente do que você tem:

SELECT * FROM dbo.OrdersImport o WHERE LEFT(OrderNumber, 3) <> "ABC" AND EXISTS ( SELECT * FROM dbo.OrdersImport WHERE LEFT(OrderNumber,3) <> "ABC" AND ID = o.ID ) 

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *