|
| Sybase9: Problemer med return-value af sp Fra : Jesper Stocholm |
Dato : 19-01-04 16:47 |
|
Jeg har følgende stored procedure (pn_ReservationLockChild):
BEGIN
DECLARE @isLocked INT
SET @isLocked = 0
SELECT @isLocked = pn_ReservationCheckObjectLock(@Id_,@objectType_,objectKey_)
IF @isLocked = 0
BEGIN
INSERT INTO Reservation
(Id,ObjectType,ObjectKey,TopObjectType,TopObjectKey)
VALUES
(@Id_,@objectType_,@objectKey_, @topObjectType_,@topObjectKey_)
COMMIT
END
RETURN @isLocked
END
Som det ses, så kalder den en anden stored procedure, der enten
returnerer 0 eller 1. Hvis den returnerer 0, skal den indsætte en
række i en tabel.
Problemet består i, at den altid evaluerer @isLocked til at være 0 -
uanset at pn_ReservationCheckObjectLock returnerer 1.
pn_ReservationCheckObjectLock er
AS
BEGIN
DECLARE @isLocked INT
SELECT
@isLocked = count(Id)
FROM
Reservation
WHERE
Id = @Id_ AND ObjectType = @objectType_ AND ObjectKey = @objectKey_
RETURN @isLocked
END
Kan I hjælpe mig med at gennemskue, hvorfor min IF-sætning altid
udføres?
Hvis jeg via ISql kører koden
SELECT pn_ReservationLockChild(1,2,80002,1,10001) /* indsæt ikke-låst obj */
SELECT pn_ReservationCheckObjectLock(1,2,80002) /* check object nu er låst */
SELECT pn_ReservationLockChild(1,2,80002,1,10001) */ indsæt obj ige */
Så returneres hhv 0 (som forventet, 0 = success), 1 (som
forventet, 1 = "er låst") og FEJL ved den sidste (hvilket ikke er
forventet). Jeg er lidt på bar bund mht årsagen til dette, så jeg vil
være taknemmelig for lidt hjælp.
pft,
--
Jesper Stocholm
http://stocholm.dk
| |
Kristian Damm Jensen (19-01-2004)
| Kommentar Fra : Kristian Damm Jensen |
Dato : 19-01-04 20:39 |
|
Jesper Stocholm wrote:
> Jeg har følgende stored procedure (pn_ReservationLockChild):
>
> BEGIN
> DECLARE @isLocked INT
> SET @isLocked = 0
> SELECT @isLocked =
> pn_ReservationCheckObjectLock(@Id_,@objectType_,objectKey_) IF
> @isLocked = 0 BEGIN
> INSERT INTO Reservation
> (Id,ObjectType,ObjectKey,TopObjectType,TopObjectKey)
> VALUES
> (@Id_,@objectType_,@objectKey_,
> @topObjectType_,@topObjectKey_) COMMIT
>
> END
> RETURN @isLocked
> END
>
> Som det ses, så kalder den en anden stored procedure, der enten
> returnerer 0 eller 1. Hvis den returnerer 0, skal den indsætte en
> række i en tabel.
>
> Problemet består i, at den altid evaluerer @isLocked til at være 0 -
> uanset at pn_ReservationCheckObjectLock returnerer 1.
>
> pn_ReservationCheckObjectLock er
>
> AS
> BEGIN
> DECLARE @isLocked INT
> SELECT
> @isLocked = count(Id)
> FROM
> Reservation
> WHERE
> Id = @Id_ AND ObjectType = @objectType_ AND ObjectKey =
> @objectKey_ RETURN @isLocked
> END
>
> Kan I hjælpe mig med at gennemskue, hvorfor min IF-sætning altid
> udføres?
>
> Hvis jeg via ISql kører koden
>
> SELECT pn_ReservationLockChild(1,2,80002,1,10001) /* indsæt
ikke-låst
> obj */ SELECT pn_ReservationCheckObjectLock(1,2,80002) /* check
> object nu er låst */ SELECT
> pn_ReservationLockChild(1,2,80002,1,10001) */ indsæt obj ige */
>
> Så returneres hhv 0 (som forventet, 0 = success), 1 (som
> forventet, 1 = "er låst") og FEJL ved den sidste (hvilket ikke er
> forventet). Jeg er lidt på bar bund mht årsagen til dette, så jeg
vil
> være taknemmelig for lidt hjælp.
>
> pft,
Du bliver ved med at bruge select til at udføre dine procedurer. Prøv
med EXEC. (Jeg er i øvrigt lidt forbløffet over at du over kan køre
overstående procedure.
--
Kristian Damm Jensen
damm (at) ofir (dot) dk
| |
Jesper Stocholm (19-01-2004)
| Kommentar Fra : Jesper Stocholm |
Dato : 19-01-04 22:07 |
|
Kristian Damm Jensen wrote :
> Jesper Stocholm wrote:
>> Jeg har følgende stored procedure (pn_ReservationLockChild):
>>
>> BEGIN
>> DECLARE @isLocked INT
>> SET @isLocked = 0
>> SELECT @isLocked =
>> pn_ReservationCheckObjectLock(@Id_,@objectType_,objectKey_) IF
>> @isLocked = 0 BEGIN
>> INSERT INTO Reservation
>> (Id,ObjectType,ObjectKey,TopObjectType,TopObjectKey)
>> VALUES
>> (@Id_,@objectType_,@objectKey_,
>> @topObjectType_,@topObjectKey_) COMMIT
>>
>> END
>> RETURN @isLocked
>> END
>>
> Du bliver ved med at bruge select til at udføre dine procedurer. Prøv
> med EXEC. (Jeg er i øvrigt lidt forbløffet over at du over kan køre
> overstående procedure.
EXEC virker ikke - men det gør EXECUTE heldigvis.
Men - jeg bruger jo SELECT, da jeg skal bruge værdien @isLocked i
SELECT @isLocked = pn_ReservationCheckObjectLock(@Id_,@objectType_,objectKey_)
IF @isLocked = 0
BEGIN
...
Hvordan skal jeg ellers "samle returværdien op"?
Jeg har i øvrigt fundet et "hack". I stedet for dette:
SELECT @isLocked = pn_ReservationCheckObjectLock(@Id_,@objectType_,objectKey_)
IF @isLocked = 0
BEGIN
Bruger jeg
IF NOT EXISTS (SELECT 1 FROM Reservation WHERE ...)
BEGIN
END
ELSE
...
Men det undrer mig stadig, at linien
IF @isLocked = 0
altid returnerede sandt. Er der nogen forklaring på det?
--
Jesper Stocholm
Gør Christiania en tjeneste - køb din hash et andet sted.
| |
Peter Lykkegaard (19-01-2004)
| Kommentar Fra : Peter Lykkegaard |
Dato : 19-01-04 22:36 |
|
Jesper Stocholm wrote:
> Men - jeg bruger jo SELECT, da jeg skal bruge værdien @isLocked i
> Hvordan skal jeg ellers "samle returværdien op"?
>
Hvad med
SET @isLocked =
> Men det undrer mig stadig, at linien
> IF @isLocked = 0
> altid returnerede sandt. Er der nogen forklaring på det?
>
Understøtter Sybase "print"?
Ex
Print 'IsLocked: ' + @IsLocked
- Peter
| |
Jesper Stocholm (19-01-2004)
| Kommentar Fra : Jesper Stocholm |
Dato : 19-01-04 23:10 |
|
Peter Lykkegaard wrote :
> Jesper Stocholm wrote:
>
>> Men - jeg bruger jo SELECT, da jeg skal bruge værdien @isLocked i
>> Hvordan skal jeg ellers "samle returværdien op"?
>>
> Hvad med
> SET @isLocked =
Det vil jeg prøve i morgen.
>> Men det undrer mig stadig, at linien
>> IF @isLocked = 0
>> altid returnerede sandt. Er der nogen forklaring på det?
>>
> Understøtter Sybase "print"?
> Ex
>
> Print 'IsLocked: ' + @IsLocked
Mjaeh, Sybase understøtter godt nok PRINT, men jeg kan ikke se resultatet
af disse print-outs nogen steder. Jeg bruger Sybase Central samt
"interactive SQL" til at tilgå databasen, og under "Messages", hvor jeg
ville antage at det ville fremgå, står der intet udover execution time.
Jeg har testet lidt mere, og det viser sig, at @isLocked altid vil have
den værdi den tildeles via SET, dvs
SET @isLocked = 1
SELECT @isLocked = pn_ReservationCheckObjectLock
IF @isLocked = 1
Vil altid returnere sand, og ligeledes
SET @isLocked = 0
SELECT @isLocked = pn_ReservationCheckObjectLock
IF @isLocked = 0
SELECT @isLocked ... har altså ingen effekt overhovedet (i dette
scenarium).
Er der ikke nogen af jer, der præcist kan forklare mig, hvorfor jeg enten
ikke kan bruge SELECT, skal bruge SET eller lignende? Jeg skyder lidt i
blinde pt, da jeg ikke kan få "deterministisk" opførsel ud af det.
Er det fx direkte forkert brug at skrive
SET @isLocked = 0
SELECT @isLocked = pn_Reservation(...)
.... og hvorfor?
--
Jesper Stocholm
Gør Christiania en tjeneste - køb din hash et andet sted.
| |
Kristian Damm Jensen (20-01-2004)
| Kommentar Fra : Kristian Damm Jensen |
Dato : 20-01-04 07:50 |
|
Jesper Stocholm wrote:
> Kristian Damm Jensen wrote :
>
>> Jesper Stocholm wrote:
>>> Jeg har følgende stored procedure (pn_ReservationLockChild):
>>>
>>> BEGIN
>>> DECLARE @isLocked INT
>>> SET @isLocked = 0
>>> SELECT @isLocked =
>>> pn_ReservationCheckObjectLock(@Id_,@objectType_,objectKey_) IF
>>> @isLocked = 0 BEGIN
>>> INSERT INTO Reservation
>>>
(Id,ObjectType,ObjectKey,TopObjectType,TopObjectKey)
>>> VALUES
>>> (@Id_,@objectType_,@objectKey_,
>>> @topObjectType_,@topObjectKey_) COMMIT
>>>
>>> END
>>> RETURN @isLocked
>>> END
>>>
>> Du bliver ved med at bruge select til at udføre dine procedurer.
Prøv
>> med EXEC. (Jeg er i øvrigt lidt forbløffet over at du over kan køre
>> overstående procedure.
>
>> o)
>
> EXEC virker ikke - men det gør EXECUTE heldigvis.
>
> Men - jeg bruger jo SELECT, da jeg skal bruge værdien @isLocked i
>
> SELECT @isLocked =
> pn_ReservationCheckObjectLock(@Id_,@objectType_,objectKey_) IF
> @isLocked = 0 BEGIN
> ...
>
> Hvordan skal jeg ellers "samle returværdien op"?
Ved hjælp af execute. Nu har jeg godt nok ikke personlige erfaringer
med Sybase9, men jeg har arbejdet med både version 6 og 10, og her er
standardmetode for at opsamle returværdien fra en procedure
execute @return_status = procedure_name @variable, ....
Ellers mener du noget andet med Sybase end jeg gør. Jeg taler om
Sybase SQLServer.
<snip>
--
Kristian Damm Jensen
damm (at) ofir (dot) dk
| |
Jesper Stocholm (20-01-2004)
| Kommentar Fra : Jesper Stocholm |
Dato : 20-01-04 08:08 |
|
Kristian Damm Jensen wrote :
> Jesper Stocholm wrote:
>> Men - jeg bruger jo SELECT, da jeg skal bruge værdien @isLocked i
>>
>> SELECT @isLocked =
>> pn_ReservationCheckObjectLock(@Id_,@objectType_,objectKey_) IF
>> @isLocked = 0 BEGIN
>> ...
>>
>> Hvordan skal jeg ellers "samle returværdien op"?
>
> Ved hjælp af execute. Nu har jeg godt nok ikke personlige erfaringer
> med Sybase9, men jeg har arbejdet med både version 6 og 10, og her er
> standardmetode for at opsamle returværdien fra en procedure
>
> execute @return_status = procedure_name @variable, ....
Ok - jeg synes bare ikke, at jeg har kunnet få det til at virke. JEg
prøver dog gerne igen.
> Ellers mener du noget andet med Sybase end jeg gør. Jeg taler om
> Sybase SQLServer.
Det gør jeg også.
--
Jesper Stocholm
Gør Christiania en tjeneste - køb din hash et andet sted.
| |
Kristian Damm Jensen (20-01-2004)
| Kommentar Fra : Kristian Damm Jensen |
Dato : 20-01-04 08:14 |
|
Jesper Stocholm wrote:
> Kristian Damm Jensen wrote :
<snip>
>> Ellers mener du noget andet med Sybase end jeg gør. Jeg taler om
>> Sybase SQLServer.
>
> Det gør jeg også.
I så fald vil jeg tilføje en kommentar vedrørende print (og testoutput
i almindelighed).
Som du selv skriver, så virker print (print "Variabel %1", @variabel)
og det gør en select hvor du ikke lægger værdien i en variabel også
(altså 'select 5+7' frem for 'select @i=5+7'). Begge dele burde levere
output til det sql-værktøj du bruger. Hvis ikke mindst én af de to
former virker, så brude du finde dig et andet værktøj, for det er
efter min mening fuldstændig uacceptabelt, at man ikke kan indsætte
testudskrifter i sin kode. Microsoft ISQL/w leverer i al fald varen.
--
Kristian Damm Jensen
damm (at) ofir (dot) dk
| |
Jesper Stocholm (20-01-2004)
| Kommentar Fra : Jesper Stocholm |
Dato : 20-01-04 09:51 |
|
"Kristian Damm Jensen" <REdammMOVE@ofir.dk> wrote in news:buikl3$hpdld$1
@ID-146708.news.uni-berlin.de:
> Jesper Stocholm wrote:
>> Kristian Damm Jensen wrote :
>
> <snip>
>
>>> Ellers mener du noget andet med Sybase end jeg gør. Jeg taler om
>>> Sybase SQLServer.
>>
>> Det gør jeg også.
>
> I så fald vil jeg tilføje en kommentar vedrørende print (og testoutput
> i almindelighed).
>
> Som du selv skriver, så virker print (print "Variabel %1", @variabel)
> og det gør en select hvor du ikke lægger værdien i en variabel også
> (altså 'select 5+7' frem for 'select @i=5+7'). Begge dele burde levere
> output til det sql-værktøj du bruger. Hvis ikke mindst én af de to
> former virker, så brude du finde dig et andet værktøj, for det er
> efter min mening fuldstændig uacceptabelt, at man ikke kan indsætte
> testudskrifter i sin kode. Microsoft ISQL/w leverer i al fald varen.
Ja, det kan du jo have ret i - men i dette tilfælde har jeg ikke noget
valg, da værktøjet er valgt af nogen, der sidder lidt højere "oppe i
fødekæden". Jeg har prøvet PRINT-kommandoerne (som jeg fandt i online
books), men jeg kan ikke "finde" output fra det nogen steder.
Jeg skal dog blankt erkende, at jeg har en mistanke om, at det i dette
tilfælde ikke er deciderede fejl med værktøjet - men måske snarere
manglende _erfaring_ med værktøjet, der er problemet ... jeg har blot
lidt problemer med at finde ud af, hvor jeg skal finde årsagen til det
problem jeg har pt.
Tak for jeres hjælp, begge to ...
--
Jesper Stocholm
http://stocholm.dk
| |
Peter Lykkegaard (20-01-2004)
| Kommentar Fra : Peter Lykkegaard |
Dato : 20-01-04 12:49 |
|
"Jesper Stocholm" wrote in a message
>
> Problemet består i, at den altid evaluerer @isLocked til at være 0 -
> uanset at pn_ReservationCheckObjectLock returnerer 1.
>
Jeg har lige prøvet et par ting
Jeg bruger ikke selv nestede procedure kald på mssql, så jeg er lidt ny udi
det
Men
Create procedure sp_CheckAField As
Declare @ACheck Int
If Exists(
Select AField from ATable -- Where 1=2
)
Set @ACheck = 1
Else
Set @ACheck = 0
Return @ACheck
Og
DECLARE @ACheck Int
exec @ACheck = sp_CheckAField
select @AField
Det virker da fint på mssql ?
Ved godt at det er sybase, men de to systemer er (eller har været ikke helt
fremmede over for hinanden
- Peter
| |
|
|