Avatar billede misbruger Nybegynder
23. marts 2006 - 14:09 Der er 1 kommentar og
1 løsning

ExecuteScalar() mangler retur værdi efter rollback

Jeg har en Stored Proc. der kører i en transaction
I starten af min Proc står...

...
BEGIN TRANSACTION
  ROLLBACK TRANSACTION
  RETURN -10
...

Når jeg afvikler den i T-SQL fra (SQL Mng Studio), kommer der også ganske rigtigt en return value = -10

Men når jeg afvikler den fra min Controller (C#)...

int error = 0
try
{
  error = Convert.ToInt32(cmd.ExecuteScalar());
}
catch(Exception e)
{
  //error er stadig = 0
  //dvs at execute scalar ikke når at
  //læse returværdien før exceptionen bliver rejst
}

Hvordan fanger jeg retur værdien fra min stored proc. når den bliver rollback'ed ?

...

Årsagen er at min proc. kan kalde rollback 5 forskellige steder, og jeg vil gerne vide hvilken del af min proc der forudsagede en rollback ?

På forhånd tak!

Mis
Avatar billede Slettet bruger
23. marts 2006 - 17:09 #1
ExecuteScalar returnerer første værdien af første kolonne i første række af et resultset og din stored procedure returnerer ikke noget result set. Du skal lave en command og definerer en parameter @return med direction ReturnValue og tage værdien af den efter brug af cmd.ExecuteNonQuery.

En sviner kunne være at lave en selec -10 i stedet for return, men det er nok ikek at foretrække.
Avatar billede misbruger Nybegynder
23. marts 2006 - 20:02 #2
ExecuteScalar burde ikke kun kunne hente først kolonne i første række...
Den burde kunne hente hvilken som helst scalar værdi.

Desuden har jeg forsøgt at lave select -10, men det havde inge effekt, fordi blemet ligger ikke deri...

Problemet derimod er at når jeg kalder rollback transaction, så rejses det som en SqlException i min controller.
Dvs at jeg kan heller ikke bruge en output parameter, som jeg læser værdien af efter cmd.ExecuteNonQuery(), eftersom at ExecuteNonQuery() vil rejse exceptionen, og dermed vil koden efterfølgende (hvor jeg læser output parameteren) ikke blive afviklet.

f.eks...
SqlParameter param = new SqlParameter("@Output", 0);
param.Direction = CommandDirection.Output;
cmd.Parameters.Add(param);

try
{
  cmd.ExecuteNonQuery();
  // Nedenstående kode bliver ikke afviklet,
  // da ExecuteNonQuery() rejser SqlException
  int errorCode = Convert.ToInt32(param.value);
}
catch(Exception e)
{
  // param.value er stadig 0 her.
}

Årsagen er at alt dette bliver afviklet inden i et TransactionScope, og derfor rejses en rollback transaction i en stored proc som en exception.

Løsning (min)...
Jeg har valgt at fjerne transactionen fra min stored procedure, og lade TransactionScope håndtere det i steden for.
Derved vil jeg kunne læse retur værdien, og rejse den rette exception, f.eks...

  cmd.ExecuteNonQuery();
  int errorCode = Convert.ToInt32(param.value);
  switch(errorCode)
  {
    case -10:
      throw new Exception("Fejl -10");
    case -20:
      ....
  }

Dermed vil det boble op gennem mit TrasactionScope som en TransactionAbortedException med min egen exception som innerException

Har fået læst op på LTM (arbejder i 2.0)

Ellers mange tak for hjælpen!
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