If Exists – Selecteer Prevent Repeating Code

We ontvangen een bestellijst en valideren dat deze begint met bepaalde prefixen, bijvoorbeeld als OrderNumber niet begint met ABC, dan weergeven bestellijst naar gebruiker als fout. We gebruiken exist, om te zoeken naar het eerste bestaan, willen niet veel prestatietijd verbruiken. Als er geen bestaat, kunnen we beginnen met het uitvoeren van een andere taak in code.

Is er hoe dan ook in sql om zich te ontdoen van de repetitieve code? We hebben veel van dit soort controles op meerdere tabellen, in een poging de code efficiënter te maken.

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 

Antwoord

Helaas ben ik bang dat als je probeert te voorkomen dat je code herhaalt, je uiteindelijk meer code schrijft en de zoekopdracht minder leesbaar maakt. Maar ik denk dat dit voordelig voor je kan zijn – houd rekening met situaties waarin je in de test alleen in een of twee tabellen hoeft te zoeken, waar je om alle details op te halen je moet aansluiten bij meerdere tabellen. In die situaties kunt u de testquery vereenvoudigen, waardoor ze ook sneller kunnen worden uitgevoerd.

En terwijl we bezig zijn, kunt u ook overwegen uw WHERE-statement te wijzigen. Het gebruik van functies in het predikaat maakt ze niet SARGable en voorkomt in die gevallen het gebruik van indexen. Een betere benadering in dit voorbeeld zou zijn om

WHERE OrderNumber LIKE "ABC%" 

te controleren aangezien de optimizer een conversie zal uitvoeren naar iets in de trant van

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

die het gebruik van indexen ondersteunt. Dit zou dus indexscan zijn (met left ()) versus index zoeken (met LIKE).

Answer

Helaas, voor verschillende redenen (niet alleen legacy) SQL heeft bijna niet alle opties en functies voor hergebruik van code die de meeste clienttalen hebben, en sommige daarvan (zoals scalaire UDFs) hebben aanzienlijke problemen. Dus als je een effectieve SQL-programmeur wilt zijn, moet je je in grote mate neerleggen bij het hergebruiken van code met knippen en plakken dan je ooit zou overwegen in een klanttaal als C #, VB. Net of Java.

Dat gezegd hebbende, u kunt de redundantie in uw voorbeeld elimineren, maar of het nu “beter is of niet, u” zult moeten beslissen.

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 

Reacties

  • Kunt u dit verder vereenvoudigen door @@ ROWCOUNT te controleren in plaats van bestaat?
  • @mathewb Ja, maar het moet onmiddellijk na de INSERT..SELECT worden gedaan. Als je nog een stelling toevoegt, dan stopt die ineens niet meer correct en probeer ik in mijn antwoorden dergelijke landmijnen te vermijden. De oplossing zou zijn om de @@ ROWCOUNT in een variabele op te slaan, maar dan zou het niet significant beter zijn dan wat ik hierboven heb.

Answer

Bevat sql hoe dan ook om de repetitieve code te verwijderen?

Niet echt, nee. U kunt de zoekopdracht als volgt herformuleren, zonder de IF-instructie, maar deze is niet echt anders dan u hebt:

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 ) 

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *