Avatar billede Lasse Novice
24. maj 2003 - 00:38 Der 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.

Jeg arbejder med vs.2003

Please hjaaeeeeeeelp
Avatar billede Lasse Novice
24. maj 2003 - 00:39 #1
Selvfoelgelig er det heller ikke en loesning at lave 2 forespoergsler fra c#, den ene der henter antal, den anden der henter selve uddraget
Avatar billede burningice Nybegynder
24. maj 2003 - 10:18 #2
prøv dog lige at fortæl os hvad det er der er så dynamisk... du har vel bare nogle rækker du skal hente ud fra en WHERE-statement? ?
Avatar billede Lasse Novice
24. maj 2003 - 18:07 #3
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 :(
Avatar billede Lasse Novice
24. maj 2003 - 19:34 #4
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!
Avatar billede burningice Nybegynder
24. maj 2003 - 19:41 #5
ææææ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 !!
Avatar billede Lasse Novice
25. maj 2003 - 20:45 #6
1) ok... lad os lige vende tilbage til spg.

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.
Avatar billede kichian Nybegynder
26. maj 2003 - 10:02 #7
I din SP indsætter du data i en temporær tabel. Tæl fra denne, hvorefter indholdet returneres.
Avatar billede Lasse Novice
26. maj 2003 - 16:47 #8
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.
Avatar billede burningice Nybegynder
28. maj 2003 - 09:56 #9
ms-help://MS.NETFrameworkSDK/cpguidenf/html/cpconinputoutputparametersreturnvalues.htm
Avatar billede burningice Nybegynder
28. maj 2003 - 09:58 #10
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

SqlParameter myParm = catDA.InsertCommand.Parameters.Add("@RowCount", SqlDbType.Int);
myParm.Direction = ParameterDirection.ReturnValue;

myParm = catDA.InsertCommand.Parameters.Add("@Identity", SqlDbType.Int, 0, "CategoryID");
myParm.Direction = ParameterDirection.Output;
Avatar billede Lasse Novice
28. maj 2003 - 17:10 #11
cyberfessor >> Ja, det lyder som en rigtig god ide, men min sekvens er lidt forskellig i forhold til den du afspejler her.

Jeg har som foelger:

CREATE PROCEDURE Test
  @rowcount int OUT
AS

SELECT * FROM tablename
SELECT @rowcount = @@rowcount

Eftersom jeg driver en masse raekker ud, laver jeg foelgende i c#(lidt pseudokode):


sqlcommand.commandtext = "Test";
sqlcommand.commandtype = storedprocedure;
sqlcommand.parameters.add("@rowcount", SqlDbType.Int);
sqlcommand.parameters["@rowcount"].directiontype = output;

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?
Avatar billede burningice Nybegynder
28. maj 2003 - 19:45 #12
uhm... hvorfor skriver du SELECT @rowcount?? det er jo en intervariabel, så det her burde gøre det:

CREATE PROCEDURE Test
AS

SELECT Count(id) AS count, felt2, felt3 FROM tablename GROUP BY id, felt2, felt3

sqlcommand.commandtext = "Test";
sqlcommand.commandtype = storedprocedure;

int rowcount = int.Parse(sqlcommand.parameters["count"].Value);
Avatar billede Lasse Novice
28. maj 2003 - 20:02 #13
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().
Avatar billede burningice Nybegynder
29. maj 2003 - 11:40 #14
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.
Avatar billede Lasse Novice
29. maj 2003 - 15:59 #15
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.
Avatar billede burningice Nybegynder
29. maj 2003 - 16:56 #16
prøv dog at spørg i mssql-kategorien istedet... det har ikke så meget med c# at gøre
Avatar billede Lasse Novice
12. august 2003 - 23:30 #17
ingen workarounds... lukker spg.
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
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

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