2012-03-26 12 views
0

Ich versuche, die Daten aus DB in einer Variablen zu speichern und es in Java-Code zurückzugeben.Umfang der Variablen in der SQL Server-Prozedur bei der Verwendung von Cursorn

Es gibt NULL-Wert zurück. Dies liegt am Umfang der Variablen im Cursor. Kann jemand eine Lösung dafür vorschlagen?

Hier ist mein Verfahren:

ALTER PROCEDURE [dbo].[rml_ups_profilerscheduler] @RuleIds varchar(200) output 
    -- Add the parameters for the stored procedure here 
    --<@Param1, sysname, @p1> <Datatype_For_Param1, , int> = <Default_Value_For_Param1, , 0>, 
    --<@Param2, sysname, @p2> <Datatype_For_Param2, , int> = <Default_Value_For_Param2, , 0> 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    DECLARE @rulescheduleid varchar(50), @scheduletype varchar(50),@finalop varchar(50) 
    DECLARE cursorName CURSOR GLOBAL 
    FOR 
    select distinct rulescheduleid,scheduletype 
    from rml_ups_ruleschedulemaster 
    OPEN cursorName -- open the cursor 
    FETCH NEXT FROM cursorName 
    INTO @rulescheduleid, @scheduletype 
    set @finalop='' 
    if(lower(@scheduletype) ='daily') 
    set @[email protected]+','+(SELECT CONVERT(varchar(150), 
    (select ruleid from rml_ups_ruleschedulemaster a,rml_ups_rulescheduletimemapping b 
    where a.rulescheduleid=b.rulescheduleid and b.schedulestarthour <= (SELECT DATEPART(hh, GETDATE())) 
    and scheduleendhour >=(SELECT DATEPART(hh, GETDATE())) 
    and a.rulescheduleid=1))) 

    -- PRINT @rulescheduleid + ' ' + @scheduletype -- print the name 
    if(lower(@scheduletype) ='weekly') 

    set @[email protected]+','+(SELECT CONVERT(varchar(150), 
    (select ruleid from rml_ups_ruleschedulemaster a,rml_ups_rulescheduletimemapping b 
    where a.rulescheduleid=b.rulescheduleid and b.schedulestarthour <= (SELECT DATEPART(hh, GETDATE())) 
    and scheduleendhour >=(SELECT DATEPART(hh, GETDATE())) and a.scheduledayofweek =(SELECT DATEPART(dw, GETDATE())) 
    and [email protected]))) 

    if(lower(@scheduletype) ='monthly') 

     set @[email protected]+','+(SELECT CONVERT(varchar(150), 
    (select ruleid from rml_ups_ruleschedulemaster a,rml_ups_rulescheduletimemapping b 
    where a.rulescheduleid=b.rulescheduleid and b.schedulestarthour <= (SELECT DATEPART(hh, GETDATE())) 
    and scheduleendhour >=(SELECT DATEPART(hh, GETDATE())) and a.scheduledayofmonth =(SELECT DATEPART(dd, GETDATE())) 
    and [email protected]))) 

    if(lower(@scheduletype) ='yearly') 

     set @[email protected]+','+(SELECT CONVERT(varchar(150), 
    (select ruleid from rml_ups_ruleschedulemaster a,rml_ups_rulescheduletimemapping b 
    where a.rulescheduleid=b.rulescheduleid and b.schedulestarthour <= (SELECT DATEPART(hh, GETDATE())) 
    and scheduleendhour >=(SELECT DATEPART(hh, GETDATE())) and a.scheduledayofmonth =(SELECT DATEPART(dd, GETDATE())) and 
    a.schedulemonth=(SELECT DATEPART(mm, GETDATE())) 
    and [email protected]))) 

    if(lower(@scheduletype) ='on at time') 

    set @[email protected]+','+(SELECT CONVERT(varchar(150), 
    (select ruleid from rml_ups_ruleschedulemaster a,rml_ups_rulescheduletimemapping b 
    where a.rulescheduleid=b.rulescheduleid and b.schedulestarthour <= (SELECT DATEPART(hh, GETDATE())) 
    and scheduleendhour >=(SELECT DATEPART(hh, GETDATE())) and a.scheduledayofmonth =(SELECT DATEPART(dd, GETDATE())) 
    and schedulemonth=(SELECT DATEPART(mm, GETDATE())) and 
    a.scheduleyear=(SELECT DATEPART(yy, GETDATE())) 
    and [email protected]))) 

    --PRINT @rulescheduleid + ' ' + @scheduletype -- print the name 
    --PRINT @@FETCH_STATUS 
    WHILE @@FETCH_STATUS = 0 
    BEGIN 
    ---PRINT @@FETCH_STATUS 

    FETCH NEXT FROM cursorName 
    INTO @rulescheduleid, @scheduletype 

    if(lower(@scheduletype) ='daily') 

    set @[email protected]+','+(SELECT CONVERT(varchar(150), 
    (select ruleid from rml_ups_ruleschedulemaster a,rml_ups_rulescheduletimemapping b 
    where a.rulescheduleid=b.rulescheduleid and b.schedulestarthour <= (SELECT DATEPART(hh, GETDATE())) 
    and scheduleendhour >=(SELECT DATEPART(hh, GETDATE())) 
    and [email protected]))) 

    -- PRINT @rulescheduleid + ' ' + @scheduletype -- print the name 
    if(lower(@scheduletype) ='weekly') 

    set @[email protected]+','+(SELECT CONVERT(varchar(150), 
    (select ruleid from rml_ups_ruleschedulemaster a,rml_ups_rulescheduletimemapping b 
    where a.rulescheduleid=b.rulescheduleid and b.schedulestarthour <= (SELECT DATEPART(hh, GETDATE())) 
    and scheduleendhour >=(SELECT DATEPART(hh, GETDATE())) and a.scheduledayofweek =(SELECT DATEPART(dw, GETDATE())) 
    and [email protected]))) 

    if(lower(@scheduletype) ='monthly') 

    set @[email protected]+','+(SELECT CONVERT(varchar(150), 
    (select ruleid from rml_ups_ruleschedulemaster a,rml_ups_rulescheduletimemapping b 
    where a.rulescheduleid=b.rulescheduleid and b.schedulestarthour <= (SELECT DATEPART(hh, GETDATE())) 
    and scheduleendhour >=(SELECT DATEPART(hh, GETDATE())) and a.scheduledayofmonth =(SELECT DATEPART(dd, GETDATE())) 
    and [email protected]))) 

    if(lower(@scheduletype) ='yearly') 

    set @[email protected]+','+(SELECT CONVERT(varchar(150), 
    (select ruleid from rml_ups_ruleschedulemaster a,rml_ups_rulescheduletimemapping b 
    where a.rulescheduleid=b.rulescheduleid and b.schedulestarthour <= (SELECT DATEPART(hh, GETDATE())) 
    and scheduleendhour >=(SELECT DATEPART(hh, GETDATE())) and a.scheduledayofmonth =(SELECT DATEPART(dd, GETDATE())) and 
    a.schedulemonth=(SELECT DATEPART(mm, GETDATE())) 
    and [email protected]))) 

    if(lower(@scheduletype) ='on at time') 

    set @[email protected]+','+(SELECT CONVERT(varchar(150), 
    (select ruleid from rml_ups_ruleschedulemaster a,rml_ups_rulescheduletimemapping b 
    where a.rulescheduleid=b.rulescheduleid and b.schedulestarthour <= (SELECT DATEPART(hh, GETDATE())) 
    and scheduleendhour >=(SELECT DATEPART(hh, GETDATE())) and a.scheduledayofmonth =(SELECT DATEPART(dd, GETDATE())) 
    and schedulemonth=(SELECT DATEPART(mm, GETDATE())) and 
    a.scheduleyear=(SELECT DATEPART(yy, GETDATE())) 
    and [email protected]))) 
    PRINT @finalop 
    set @[email protected] 
    PRINT @RuleIds 
    -- print the name 

    END 
    --set @[email protected] 
    --PRINT @RuleIds 
    CLOSE cursorName 
    -- close the cursor 
    --PRINT @RuleIds 
    DEALLOCATE cursorName 
    -- Deallocate the cursor 


END 

Antwort

1

Dieses Bit:

WHILE @@FETCH_STATUS = 0 
BEGIN 
---PRINT @@FETCH_STATUS 

FETCH NEXT FROM cursorName 
INTO @rulescheduleid, @scheduletype 

ist definitiv falsch - @@FETCH_STATUSFETCH Aussage über das Ergebnis der vorherigen Basis aktualisiert wird - aber Sie haben bereits verwendet die Ergebnis dieser FETCH, bevor Sie diese Schleife erreichen, und dann führen Sie sofort eine weitere FETCH und überprüfen Sie nicht, es ist der Erfolg, bis Sie es verwendet haben.

Das würde übliche Form sein:

DECLARE <cursor> 
OPEN <cursor> 

FETCH NEXT FROM <cursor> 
WHILE @@FETCH_STATUS = 0 
BEGIN 
    <process result from previous fetch> 

    FETCH NEXT FROM <cursor> 
END 

CLOSE <cursor> 
DEALLOCATE <cursor> 

Bei einer Vermutung, wann immer Sie über das Ende der Ergebnismenge gehen, ist es die lokalen Variablen einstellen (zB @rulescheduleid) auf NULL, und Sie dann‘ Er führt eine Verkettung mit NULL durch, wobei NULL-Ergebnisse erzeugt werden.

Davon abgesehen, habe ich den Rest der Codewand nicht durchgelesen, um herauszufinden, was Sie zu tun versuchen und ob ein Cursor überhaupt benötigt wird.

+1

Guter Punkt darüber, ob der Cursor benötigt wird, immer erwähnenswert, +1. –

+0

Ich hatte meine Code-Prozedur geändert wird ohne Fehler ausgeführt, aber am Ende der Schleife Werte (von db basierend auf conditoins abgerufen) zugewiesen zu einer Variablen wird leer, nachdem die Schleife hier abgeschlossen ist, ist mein geänderter Code – ameenulla

0

Grundsätzlich ist Ihr Cursor wie folgt organisiert:

open cursor 

fetch first row into vars 

process the fetched values 

while @@fetch_status = 0 

    fetch next row into vars 
    process the fetched values 

end 

close cursor 

Nun wird der process the fetched values Teil in Ihrer Prozedur beträchtlich ist, und es wird zweimal im Code wiederholt, das ist eine Sache. Eine andere, wichtigere Sache ist, wenn Sie die abgerufenen Werte in Ihrem Schleifenkörper verarbeiten, tun Sie es im Wesentlichen unmittelbar nachdem die Werte abgerufen werden. Aber wenn es die letzte Iteration ist, wird es NULLs abrufen, und als Ergebnis der Verarbeitung der NULL-Werte endet Ihre Ausgabevariable ebenfalls mit NULL.

Also, was sollten Sie in dieser Situation tun? fällt nur die process the fetched values Stufe vor der Schleife und die andere bewegen, die nach dem fetch next row into vars Schritt ist, in die Position vor es, so dass die Struktur des Cursors, wie dies zu:

open cursor 

fetch first row into vars 

while @@fetch_status = 0 

    process the fetched values 
    fetch next row into vars 

end 

Auf diese Weise, Sie haben nur einen Platz, an dem Sie die Werte und verarbeiten. Sie machen es nur, wenn die Werte nicht NULL sind, denn sobald ein anderer FETCH NEXT die Nullwerte hervorruft, verlassen Sie die Schleife und behalten die kumulierte Ausgabe bei.

+0

ich meine geändert hatte Code-Prozedur läuft ohne Fehler, aber am Ende der Schleife Werte (von db basierend auf conditoins abgerufen) zugewiesen zu einer Variablen wird leer, nachdem die Schleife hier abgeschlossen ist, ist meine modifizierte Code – ameenulla

+0

ich hatte meine Code-Prozedur geändert wurde ohne ausgeführt jeder Fehler, aber am Ende der Schleife Werte (von db basierend auf conditoins reentred) zugewiesen zu einer Variablen wird leer, nachdem die Schleife abgeschlossen ist hier ist mein modifizierter Code Ich habe meinen modifizierten Code auch eingefügt – ameenulla

0
i had modified my code procedure is running without any error but at the end of the loop values(retrived from db based on conditoins) asaigned to a variable is becoming empty after the loop is completed here is my modified code 

Satz @ RuleIds = '' DECLARE @RuleIds ERKLÄREN cName CURSOR FÜR eindeutige ID wählen, stype von table1 OPEN cursor - öffnen Sie den Cursor VON cName @rul INTO FETCH NEXT, @sche

WHILE @@FETCH_STATUS = 0 
BEGIN 
if(lower(@sched) ='daily') 
set @[email protected]+','+(SELECT CONVERT(varchar(150), 
(select ruleid from rml_ups_ruleschedulemaster a,rml_ups_rulescheduletimemapping b 
where a.rulescheduleid=b.rulescheduleid and b.schedulestarthour <= (SELECT DATEPART(hh, GETDATE())) 
and scheduleendhour >=(SELECT DATEPART(hh, GETDATE())) 
and [email protected]))) 
-- here iam trying to store retreved values in to variable and returning to the java code it is retuning null values 
PRINT @RuleIds 
-- it prints the values assaigned to @RuleIds variable ex values(13,12,2) 
FETCH NEXT FROM cName 
INTO @rul, @sche 
END 
CLOSE cName 
DEALLOCATE cName 
--after deaalocating of cursor the valuse stored in @RuleIds(variable) is becoming empty 
PRINT @RuleIds 
---this print statement printing nothing 
+0

Dies ist eine Frage und Antwort basiert Website - das ist keine Antwort - Sie sollten stattdessen Ihre Frage bearbeiten *, um neue Informationen hinzuzufügen. Beachten Sie auch, dass die obige Formatierung eher kaputt ist - experimentieren Sie mit den Formatierungstools und fügen Sie Ihrer Frage einen ordentlichen Bearbeitungsschritt hinzu. –

0

Persönlich würde ich überhaupt keinen Cursor verwenden.Ich würde CASE Anweisungen in einer Auswahl verwenden, um die Felder zu erhalten, die Sie zurück an die App senden möchten, und den gesamten Datensatz zurückgeben. Dann würde ich den Datensatz auf der Anwendungsseite durchlaufen, um die Parameterwerte wie von der App benötigt einzustellen.

Verwandte Themen