2012-03-26 63 views
0

我試圖將從DB中檢索到的數據存儲到一個變量中並將其返回給java代碼。SQL Server過程中使用遊標時的變量範圍

它返回NULL值。這是因爲遊標中變量的範圍。任何人都可以提出解決方案嗎?

這裏是我的方法:

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 

回答

1

該位:

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

FETCH NEXT FROM cursorName 
INTO @rulescheduleid, @scheduletype 

肯定是不對的 - @@FETCH_STATUS是基於以前FETCH語句的結果更新 - 但你已經使用了在達到這個循環之前,你會得到FETCH的結果,然後你立即執行另一個FETCH,並且在你使用它之前不要檢查它是否成功。

通常的形式是:

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> 

在猜測,當你路過的結果集的結尾,它的設置本地變量(如@rulescheduleid)爲NULL,然後你」重新執行與NULL連接產生NULL結果。這就是說,我沒有仔細閱讀代碼的其餘部分來確定你正在嘗試做什麼以及是否需要光標。

+1

關於是否需要光標,總是值得一提的是+1。 – 2012-03-26 07:37:04

+0

我已經修改我的代碼過程運行沒有任何錯誤,但在循環結束後,循環結束時(從基於conditoins的數據庫中回收)賦值爲變量在循環完成後變爲空,這裏是我的修改代碼 – ameenulla 2012-03-27 15:25:29

0

基本上,你的光標舉辦這樣的:

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 

現在,process the fetched values部分是在你的程序相當大的,它是在你的代碼,這是一兩件事重複兩次。另一件更重要的事情是,當你在循環體中處理提取的值時,你基本上是在取值之後立即執行它。但是,如果它是最後一次迭代,它將獲取NULL,並且由於處理NULL,結果輸出變量也最終爲NULL。

那麼,在這種情況下你應該怎麼做?循環之前剛落process the fetched values階段,前移到另外一個,這是fetch next row into vars步驟之後,該位置,使光標的結構變成這樣:

open cursor 

fetch first row into vars 

while @@fetch_status = 0 

    process the fetched values 
    fetch next row into vars 

end 

這樣,你只有一個地方正在處理值只有當值不爲NULL時,你纔會這樣做,因爲只要另一個FETCH NEXT產生NULL值,就退出循環,保留累積輸出。

+0

我修改了我的代碼過程運行時沒有任何錯誤,但在循環結束後,循環結束時(從基於conditoins的db中恢復)賦值給一個變量變爲空,這裏是我修改後的代碼 – ameenulla 2012-03-27 15:12:06

+0

我修改了我的代碼過程,沒有運行任何錯誤,但在循環結束時(基於conditoins從數據庫中回收的),在循環完成後變爲空,這裏是我修改的代碼,我粘貼了我的修改後的代碼 – ameenulla 2012-03-27 15:26:26

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 

組@ RuleIds = '' DECLARE @RuleIds DECLARE CNAME CURSOR FOR 從表1 選擇不同的ID,S類型 OPEN CursorName中 - 打開光標 NEXT FROM CNAME FETCH INTO @rul, @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

這是一個基於問題和答案的問答網站 - 這不是一個答案 - 你應該,而不是,編輯*你的問題,以添加新的信息。另外請注意,上面的格式是相當破碎 - 嘗試格式化工具,並添加一個體面的編輯您的問題。 – 2012-03-27 17:54:02

0

就個人而言,我根本不會使用遊標。我會在select中使用CASE語句來獲取要發送迴應用的字段並返回整個數據集。然後,我會循環訪問應用程序端的數據集,以根據應用程序的需要設置參數值。