Hvis eksisterer – Velg Forhindre gjentatt kode

Vi mottar en ordreliste, og validerer den starter med visse prefikser, for eksempel hvis OrderNumber ikke starter med ABC, enn visning bestillingsliste til bruker som feil. Vi bruker eksisterer, for å søke etter første eksistens, vil ikke konsumere mye ytelsestid. Hvis ingen eksisterer, kan vi begynne å utføre en annen oppgave i kode.

Er det allikevel i sql å bli kvitt den gjentatte koden? Vi har mange sjekker som dette på flere tabeller, og prøver å gjøre koden mer effektiv.

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 

Svar

Dessverre er jeg redd ved å prøve å forhindre at du gjentar kode, kan du ende opp med å skrive mer kode og gjøre spørringen mindre lesbar. Men jeg tror dette kan være fordelaktig for deg – ta hensyn til situasjoner der du i testen bare ville trenge å søke i en eller to tabeller, der du for å hente alle detaljene må bli med i flere. I slike situasjoner kan du forenkle testspørringen og dermed gjøre dem raskere å utføre.

Og mens vi er i gang, kan du også vurdere å endre WHERE-setningen. Ved å bruke funksjoner i predikatet blir de ikke SARGable og forhindrer bruk av indekser i slike tilfeller. En bedre tilnærming i dette eksemplet vil være å sjekke

da optimalisereren vil utføre konvertering til noe i retning av

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

som støtter bruk av indekser. Så dette ville være indeksskanning (ved bruk av venstre ()) mot indekssøk (ved hjelp av LIKE).

Svar

Dessverre, for av forskjellige årsaker (ikke bare eldre) SQL har ikke nesten alle kodeanvendelsesalternativene og funksjonene som de fleste klientspråk har, og noen av dem (som skalære UDFer) har betydelige problemer. Så i stor grad, hvis du vil være en effektiv SQL-programmerer, må du si deg fra til å gjøre mye mer klipp-og-lim inn kodebruk enn du noen gang ville tenkt på et klientspråk som C #, VB. Net eller Java.

Når det er sagt, kan du eliminere overflødigheten i eksemplet ditt, men om det faktisk er bedre eller ikke, må du bestemme deg.

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 

Kommentarer

  • Kan du forenkle dette ytterligere ved å sjekke @@ ROWCOUNT i stedet for å eksistere?
  • @mathewb Ja, men det må gjøres umiddelbart etter INSERT..SELECT. Hvis du legger til et nytt utsagn, slutter det plutselig å virke riktig, og jeg prøver å unngå landminer slik i svarene mine. Løsningen ville være å lagre @@ ROWCOUNT i en variabel, men da ville det ikke være vesentlig bedre enn det jeg har ovenfor.

Svar

Er det uansett i sql å kvitte seg med den repeterende koden?

Ikke egentlig, nei. Du kan omformulere spørringen slik uten IF-setningen, men det er ikke veldig forskjellig fra det du har:

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 ) 

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *