Avatar billede _just4fun_ Nybegynder
29. marts 2006 - 22:40 Der er 10 kommentarer og
1 løsning

in (@aVarChar)

Jeg har en liste af tekster som bruges i en  query som denne:

select somedata from table where id in ('t1', 't2', 't3');

Men hvis jeg gør som følgende :

declare @mystrings varchar(3000);
set @mystrings = '''t1'', ''t2'', ''t3''';
select somedata from table where id in (@mystrings);

Så virker det ikk... hvad går der galt, og hvordan får jeg det til at virke??

Problemet bunder i at selve queryen ligger i en storedProcedure, og de tekster der skal spørges på (mystrings) kommer ind som en varchar.

Mvh J
Avatar billede arne_v Ekspert
29. marts 2006 - 23:05 #1
@mystrings er en vaerdi med kommaer i

't1', 't2', 't3' er 3 vaerdier adskilt af komma

absolut ikke det samme

exec('select somedata from table where id in (' + @mystrings + ')')

vil nok virke men performance er ikke super
Avatar billede trer Nybegynder
29. marts 2006 - 23:06 #2
Beklager.  Det kan man ikke...

Det du *kan* gøre er at omskrive hele din stored procedure til dynamisk sql - men det vil give dårligere ydelse / belaste serveren mere.

declare @mystrings varchar(3000), @sql varchar(8000)
set @mystrings = '''t1'', ''t2'', ''t3''';
set @sql = 'select somedata from table where id in ('+@mystrings+')'
exec (@sql)
Avatar billede _just4fun_ Nybegynder
30. marts 2006 - 07:53 #3
jeg gør allerede som I nævner, og tror det er pga. dette jeg er løbet i performance-problemer. Havde håbet på at der var en form for split-kommando der kunne dele listen ind i en temp-tabel, og derefter bruge temp-tabellen i en almindelig query.  Der kan være 5-50 værdier i listen (ekstern data, så jeg har ikke umiddelbart adgang til dem for at lave det om) og tror derfor ikke der er mere performance i at lave en for-lykke der splitter teksten op, og derefter smider den i temp-tabellen....
Nogen ideer?
Avatar billede trer Nybegynder
30. marts 2006 - 17:48 #4
Ideer?

Heh - opgrader til SQL Server 2005 og omskriv T-SQL koden til en CLR. Ikke at det løser det grundlæggende problem - eksekveringen af løkken bliver bare hurtigere...

Ellers er der kun hurtigere cpu'er at håbe på - men skaleringen vil stadig være i skoven.
Avatar billede _just4fun_ Nybegynder
30. marts 2006 - 19:13 #5
prøver lige med denne først inde i SP'en:

DECLARE @t TABLE(id INT);
INSERT @t (id) EXEC('select Id from table where datxt in ('''+@mystrings+  ''')');

På den måde kan jeg lave hele det oprindelige udtryk der blev kørt via exec om til en almindelig join med t@, og på den måde lade optimizeren vide hvad der sker... ActualExecutionPlan mener at den nye belaster 14% i forhold til den gamles 86%.. hmmmm, det skal prøves....
Avatar billede trer Nybegynder
30. marts 2006 - 19:25 #6
Interessant. Du må godt lige lade høre hvad det aktuelle resultat bliver...
Avatar billede _just4fun_ Nybegynder
30. marts 2006 - 19:26 #7
Det ser ud til at det virkede på et eller andet plan. Er nu nede i en middel cpu-load på langt under 1/3 af det oprindelige.

trer->Har du en kodestump eller en link?? det kunne da være sjovt at se om det havde nogen effekt at lave det med en funktion istedet!!!
Avatar billede trer Nybegynder
30. marts 2006 - 19:31 #8
Desværre ikke. Men det er kun en vbstump du skal skrive.  Der er dog et ups i performance med CLR: Hvis en clr ryger ud af assembly cachen tager det forholdvis lang tid at få den ind igen - omkring 1 sekund.

I øvrigt - prøv for sjovs skyld at ændre din tabel-variabel til en temporær variabel og sammenlign performance, specielt ved mange rækker / data.
Avatar billede _just4fun_ Nybegynder
30. marts 2006 - 19:45 #9
hehe.. jeg napper gerne 1 sekund hist og pist hvis det kan gøre noget ved de ca. 250000 queries der er i døgnet ;-)

Jeg har tidligere moret mig med #-tabeller, og synes der var noget bøvl med at man selv skulle rydde op for ikke at komme til at lave 2 tabeller med samme navn (hvis den oprindelige af en eller anden grund ikke var død endnu).

Tjekker lige op på CLRen
Avatar billede trer Nybegynder
30. marts 2006 - 19:49 #10
Jep - temporære tabeller har nogle ulemper. Bl.a. bruger de også låse-ressourcer. På SQL Server 2000 er der dog en detalje - query optimizeren forventer altid 1 række i en tabel-variabel mens den bruger statistikkerne til at finde ud af antallet i en temporær tabel. Det kan give performance udsving når der er mange rækker i en tabelvariabel ifht temporær tabel.  Jeg ved ikke hvordan MsSQL 2k5 er på det punkt.

Men held og lykke.
Avatar billede _just4fun_ Nybegynder
30. marts 2006 - 20:49 #11
høhø... jeg skal NOK komme til at more mig med hjemmelavede funktioner... DAMN hvor er det nemt at lave inde fra VS!
Anyway... Det virkede lidt fjollet at lave en C#-funktion der lavede en select for derefter at returnere den selvsamme select i en nyoprettet tabel når jeg ikke skal have mere data tilbage end jeg skal. Jeg lader den ligge der, og drømmer sødt om at komme i gang med c# på Sql2K5.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester