"Jimmy" <pleasereplyingroup@hotmail.com> skrev i en meddelelse
news:3f5f1313$0$13173$edfadb0f@dread15.news.tele.dk...
> Hey
>
> Spørgsmål 1:
> Har et sqlkald som ser således ud:
> streng = "and (felt2 = 'vaerdi1' or felt2 = 'vaerdi2') 'Ved godt at jeg
> måske burde have haft lavet en "in" her, men kan vi lige se bort fra det
:)
> "Select count(*) from tabel where felt1 = '" & var1 & "' " & streng
>
> Har prøvet at lave det om til en stored procedure som bliver kaldt på
denne
> her måde:
> CREATE PROCEDURE [OWNER].[proc_name]
> @var1 nvarchar(20),
> @streng nvarchar(255)
> AS
> Select count(*) from tabel where felt1 = @var1 + @streng
> GO
>
> EXEC proc_name '3001', [ and (felt2 = 'vaerdi1' or felt2 = 'vaerdi2')]
Lad mig se:
Når proc_name bliver kald får @var1 værdien "3001" og @streng værdien "and
(felt2 = 'vaerdi1' or felt2 = 'vaerdi2')"
Den select der udføres bliver dermed:
Select count(*) from tabel where felt1 = "3001" + "and (felt2 = 'vaerdi1' or
felt2 = 'vaerdi2')"
Under de omstændigheder kan det vist ikke overraske, at du ikke får det
forventede resultat
> Kører fint bortset fra at den første SQL returnerer 1 og den anden SQL
> returnerer 0 (altså den med stored procedures)
>
> Hvad gør jeg galt?
> ...og er der overhovedet nogen ide i at lave dette om til en stored
> procedure når jeg alligevel danner det meste af where klusulen i en
> variabel?
Det kommer an på, hvad du ønsker i det generelle tilfælde. Hvis du kan leve
med en procedure, der ser således ud:
CREATE PROCEDURE [OWNER].[proc_name]
@var1 nvarchar(20),
@vaerdi1 nvarchar(255),
@vaerdi2 nvarchar(255)
AS
Select count(*) from tabel
where felt1 = @var1
and (felt2 = @vaerdi1 or felt2 = @vaerdi2)
altså, hvis du altid har netop den struktur på din select, så er det en fin
idé. Ellers havner du i at skulle lave dynamisk sql inde i proceduren. Det
kan godt lade sig gøre (i al fald i de varianter, jeg kender til), men hvis
der ikke er overbevisende argumenter for det, kan du lige så godt føre det i
værtssproget.
> Spørgsmål2:
> Har lavet lavet en insert om til en stored procedure på samme måde. Dette
> virker til gengæld upåklageligt.
> Insert into tabel (felt1, felt2, felt3, felt4, felt5) values ('" & var1 &
> "', '" & var2 & "', '" & var3 & "', '" & var4 & "', '" & var5 & "')
>
> Er lavet om til:
> CREATE PROCEDURE [OWNER].[proc_name2]
> @var1 nvarchar(20),
> @var2 nvarchar(255),
> @var3 nvarchar(255),
> @var4 nvarchar(10),
> @var5 nvarchar(20)
> AS
> Insert into tabel (felt1, felt2, felt3, felt4, felt5) values (@var1,
@var2,
> @var3, @var4, @var5)
> GO
>
> exec proc_name2 'testtekst1', 'testtekst2', 'testtekst3', 'testtekst4',
> 'testtekst5'
>
> Jeg har lavet nogle målinger for hvor hurtigt mit program kørte, men de
kan
> selvfølgelig være påvirket af anden aktivitet på SQL Serveren. Med den
> manuelle SQL lavede jeg 3 test:
> 1. 23 sek
> 2. 22 sek
> 3. 23 sek.
>
> Med den stored procedure:
> 1. 51 sek.
> 2. 24 sek.
> 3. 17 sek.
> 4. 17 sek.
>
> Min umiddelbare vurdering er at det går meget hurtigere med insert som en
> stored procedure. Kan jeg tage fejl her?
Et meget typisk mønster. En af fordelene ved en stored procedure er at
eksekveringsplanen laves én gang for alle, fremfor hver gang du udfører din
sql (med mindre du netop benytter dynamisk sql, eller på anden måde
gennemtvinger en genoversættelse hver gang). Derfor tager proceduren længere
tid at udføre 1. gang men er hurtigere ved de efterfølgende kørsler.
> Da jeg kom selecten på (fra spørgsmål 1) som en stored procedure (den
kørte
> den jo trods alt selvom den returnerer noget forkert), så tiderne således
ud
> her:
> 1. 35 sek.
> 2. 18 sek.
> 3. 29 sek.
> 4. 18 sek.
>
> Ikke en gang kom jeg ned under 17, og derfor konkluderer jeg at SQLen fra
> spørgsmål 1, vil være en dårlig ide at køre som en stored procedure.
Da de to ikke laver det samme stykke arbejde, er en sammenligning
meningsløs.
> P.S. Hvis nogen undrer sig over hvorfor jeg har sådan nogle høje tider kan
> jeg lige fortælle at programmet bliver brugt til at læse linier fra en
> tekstfil, hvor der som regel ligger flere tusinder af linier. Hver linie
> skal behandles ved at jeg checker for om den allerede findes i systemet.
> Hvis den ikke gør bliver den lagt ind.
Index, index, index. Der findes i øvrigt i mange systemer faciliteter, der
gør netop det arbejde for dig. I Sybase kan man fx oprette et clustered
index med ignore_dup_row. Herefter vil basen blot ignorere alle forsøg på at
indsætte dubletter!
Vh
Kristian