Primim o listă de comenzi și o validăm începând cu anumite prefixe, de exemplu dacă Numărul de ordine nu începe cu ABC, decât afișajul lista de comenzi către utilizator ca eroare. Folosim există, pentru a căuta prima existență, nu dorim să consumăm mult timp de performanță. Dacă nu există, atunci putem începe să efectuăm alte sarcini în cod.
Există oricum în sql pentru a scăpa de codul repetitiv? Avem multe verificări de acest fel pe mai multe tabele, încercând să facem codul mai eficient.
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
Răspuns
Din păcate, mă tem că încercând să împiedic repetarea codului, s-ar putea să ajungeți să scrieți mai multe coduri și să faceți interogarea mai puțin lizibilă. Dar cred că acest lucru poate fi avantajos pentru dvs. – luați în considerare situațiile în care la test ar trebui să căutați doar într-unul sau două tabele, unde pentru a prelua toate detaliile va trebui să vă alăturați mai multor. În aceste situații, puteți simplifica interogarea de testare, făcându-le, de asemenea, mai rapide de executat.
Și, în timp ce ne aflăm, puteți lua în considerare și modificarea instrucțiunii WHERE. Utilizarea funcțiilor în predicat le face să nu fie SARGable și să împiedice utilizarea indexurilor în aceste cazuri. O abordare mai bună în acest exemplu ar fi să bifăm
WHERE OrderNumber LIKE "ABC%"
deoarece optimizatorul va efectua conversia în ceva de-a lungul liniilor
OrderNumber >= "ABC" AND OrderNumber < "ABD"
care acceptă utilizarea indexurilor. Deci, aceasta ar fi Scanarea indexului (folosind stânga ()) versus Căutarea indexului (folosind LIKE).
Răspuns
Din păcate, pentru o varietate de motive (nu doar vechi) SQL nu are aproape toate opțiunile și caracteristicile de reutilizare a codului pe care le au majoritatea limbajelor clientului și unele dintre ele (cum ar fi UDF-urile scalare) au probleme semnificative. Deci, în mare măsură, dacă doriți să fiți un programator SQL eficient, trebuie să vă resemnați să refaceți mai mult codul tăiat și lipit decât ați considera vreodată într-un limbaj client precum C #, VB. Net sau Java.
Acestea fiind spuse, puteți elimina redundanța din exemplul dvs., totuși, indiferent dacă este de fapt mai bine sau nu, va trebui să decideți.
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
Comentarii
- Ați putea simplifica acest lucru verificând @@ ROWCOUNT în loc să existe?
- @mathewb Da, dar trebuie făcut imediat după INSERT..SELECT. Dacă adăugați o altă afirmație, atunci încetează brusc să funcționeze corect și încerc să evit minele terestre așa în răspunsurile mele. Soluția ar fi să salvați @@ ROWCOUNT într-o variabilă, dar atunci nu ar fi semnificativ mai bună decât ceea ce am mai sus.
Răspuns
Există oricum în sql pentru a scăpa de codul repetitiv?
Nu chiar, nu. Puteți reformula interogarea astfel, fără declarația IF, dar nu este cu adevărat diferită de ceea ce aveți:
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 )