24. maj 2003 - 00:38Der er
16 kommentarer og 1 løsning
stored procedure, OUT og dynamic sql statement fra c#
Jeg skal have lavet en forespoergsel. Den er yderst dynamisk, saa jeg ved ikke hvor det er smartest at generere den - fra c# eller i en stored procedure. Det er sikkert nemmest fra c#, men jeg er ogsaa interesseret i noget andet.
Udover resultatet vil jeg gerne vide hvor mange raekker jeg faar tilbage, inden jeg raeser dem igennem. Derfor har jeg taenkt paa at lave en stored procedure, som har en out parameter = @@rowcount.
Alligevel er det ikke en god ide, da jeg helst ikke ser brug af dynamisk sql(EXECUTE 'sql saetning') pga. hastighed. Ydover det er det sikkert et helvede at skulle bygge den op via streng operationer i transact-sql. Da den er yderst dynamisk, saa kan jeg heller ikke opbygge den stored procedure som: IF bla IF bla2 IF bla3 SELECT ... ELSE SELECT ... ELSE SELECT... ELSE SELECT ...
Det vil simpelthent blive for rodet, og ikke saerlig venligt at skulle vedligeholde...
Hvad goer jeg? Jeg har ikke set at det er muligt fra c# at faa at vide hvor mange rows jeg har faaet tilbage(mm. man ligger det over i en datatable, hvilket ikke er oenskeligt) foer jeg raeser dem igennem.
I dette særtema om aspekter af AI ser vi på skiftet fra sprogmodeller til AI-agenter, og hvordan virksomheder kan navigere i spændet mellem teknologisk hastighed og behovet for menneskelig kontrol.
Problemet er, at der nok er 35 forskellige kombinationer af hvordan sql saetningen kan se ud(derfor er det ikke muligt at HardCode dem). Det der aendrer sig er filtre(where) og joins(baade inner og outer).
Jeg kunne jo goere det ved at kalde en sp der har 2 parametre(en in og en out) a la:
exexQuery(sqlsentence varchar(2000), rowcount int out)
her har jeg mulighed for at generere den dynamiske sql saetning paa c# siden, hvilket goer at jeg ikke skal lave den via string ops. i transact sql. Her skal jeg dog sende en masse data over hver gang jeg vil eksekvere denne(hvor stort er overheadet paa det) og sql saetningen skal kompileres hver gang (istedet for den modsatte loesning hvor den HC)
Hvad er egentlig forskellen(hastighedsmaessigt) paa at eksekvere en query igennem EXEC 'sqlsentence' og at goere det via c# interfacet.... altsaa en commandtext = 'sqlsentence'
Den bedste loesning ville vaere at man havde en property i ens dtr der fortaeller hvor mange rows der er hentet, men jeg formoder at dette ikke findes :(
Naa, nu har jeg lige testet, og det er ikke muligt at hente ens OUTPUT parametre FOER ens datareader er lukket, saa denne loesning er ligesaa daarlig som de andre. Det ender nok med at den bedste loesning(daarlig er den nu alligevel) er at proppe alt sammen ind i et dataset(datatable), og derfra kan jeg lege med det... Dette er virkelig begraenset!
ææææh... noget siger mig at du skal seriøst skal kigge lidt på databasedesign... hvis du har 35 forskellige kombinationer laver du 35 forskellige Procedures, sværere er det ikke...
dog burde du ikke have så mange muligheder for det samme !!
Udover resultatet vil jeg gerne vide hvor mange raekker jeg faar tilbage, inden jeg raeser dem igennem. Derfor har jeg taenkt paa at lave en stored procedure, som har en out parameter = @@rowcount. - dette har jeg fundet ud af ikke er muligt!
2) Jeg har at goere med en soegemaskine hvor der kan slas ting fra/til. Det medfoerer, at der kan komme saa mange muligheder. Med tiden skal det udvides og endnu flere muligheder vil komme til.
3) Nej, det er ikke smart at hardcode saa mange forskellige procedures! Genbrug er altid smartest, 1 pga. man er jo doven, 2 pga. at det er nemmere at vedligeholde hvis der skal aendringer eller lign. til.
4) Hvis det eneste du kan bidrage med er din daarlige tone, saa ehoever du ikke komme med flere kommentarer.
hvis jeg indsaetter det i en temporaer tabel, saa kan jeg vel stadig ikke udtraekke begge vaerdier samtidig. Det jeg allerhelst vil er at udtraekke begge vaerdier samtidig...
eller er det mig der har misforstaaet ideen kichian.
Hvis ideen er at du vil lave 2 select statements, saa er ideen maaske brugbar, men saa skal jeg vaere sikker paa at andre ikke udfoerer samme funktionalitet samtidig, eller ogsaa skal jeg til at bruge transactions.... men det er maaske den eneste udvej dette... selvom det ikke er nogen smuk udvej.
Mht. maaden med datatable, saa giver det heller ikke samme funktionalitet, eftersom jeg jo udtraekker alt dataen i en datatable, og det er jo lige praecis den process jeg gerne vil overvaage.
Oev oev, hvor virker dette dog begraenset. Man skulle skrive til .net producenterne, at man skulle have en property Rowcount der baseres paa db'ens @@ROWCOUNT.
husk at din parameter skal have den rigtige direction
CREATE PROCEDURE InsertCategory @CategoryName nchar(15), @Identity int OUT AS INSERT INTO Categories (CategoryName) VALUES(@CategoryName) SET @Identity = @@Identity RETURN @@ROWCOUNT
System.data.sqlclient.sqldatareader dtr = sqlcommand.executedatareader(); int rowcount = (int)sqlcommand.parameters["@rowcount"].Value; // Dette fejler, eftersom man IKKE kan have en datareader aaben, samtidig med at man henter OUTPUT vaerdier.
Jeg kan ikke rigtig bruge return values i denne situation pga. datareaderen, eller er det mig dig "misser noget" her?
Det ville ogsaa virke, men problemet er at jeg samtidig gerne vil have alle raekker ud. Det skyldes at selve querien er temmelig indviklet og tager noget tid at eksekvere, saa derfor oensker jeg ikke koere den 2 gange(den ene hvor jeg kun uddriver count). Derfor er loesningen forhaabentlig ikke count().
uhm... du kan prøve at kigge i manualen til MS SQL om der er en intern variabel til det... @@RowCount er jo til, f.eks. hvor mange rækker der er blevet opdateret eller indsat.
ja, den kan ogsaa bruges til at se hvor mange rows man selekterer. Men det er slet ikke der problemet ligger. Problemet er at jeg i samme udtraek vil have begge ting at vide, og at jeg skal kunne kigge paa rowcount foer jeg traekker kolonner ud.
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.