我正在尝试将从DB检索到的数据存储到一个变量中并将其返回到java代码。
返回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 @finalop=@finalop+','+(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 @finalop=@finalop+','+(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 a.rulescheduleid=@rulescheduleid)))
if(lower(@scheduletype) ='monthly')
set @finalop=@finalop+','+(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.rulescheduleid=@rulescheduleid)))
if(lower(@scheduletype) ='yearly')
set @finalop=@finalop+','+(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 a.rulescheduleid=@rulescheduleid)))
if(lower(@scheduletype) ='on at time')
set @finalop=@finalop+','+(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 a.rulescheduleid=@rulescheduleid)))
--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 @finalop=@finalop+','+(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=@rulescheduleid)))
-- PRINT @rulescheduleid + ' ' + @scheduletype -- print the name
if(lower(@scheduletype) ='weekly')
set @finalop=@finalop+','+(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 a.rulescheduleid=@rulescheduleid)))
if(lower(@scheduletype) ='monthly')
set @finalop=@finalop+','+(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.rulescheduleid=@rulescheduleid)))
if(lower(@scheduletype) ='yearly')
set @finalop=@finalop+','+(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 a.rulescheduleid=@rulescheduleid)))
if(lower(@scheduletype) ='on at time')
set @finalop=@finalop+','+(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 a.rulescheduleid=@rulescheduleid)))
PRINT @finalop
set @RuleIds=@finalop
PRINT @RuleIds
-- print the name
END
--set @RuleIds=@finalop
--PRINT @RuleIds
CLOSE cursorName
-- close the cursor
--PRINT @RuleIds
DEALLOCATE cursorName
-- Deallocate the cursor
END
答案 0 :(得分: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结果。< / p>
话虽如此,我还没有通过代码墙的其余部分来阅读你想要做的事情以及是否需要光标。
答案 1 :(得分: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,退出循环,保留累积输出。
答案 2 :(得分: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 对于 选择不同的id,stype 来自table1 OPEN cursorName - 打开光标 FETCH NEXT FROM cName INTO @ rul,@ sche
WHILE @@FETCH_STATUS = 0
BEGIN
if(lower(@sched) ='daily')
set @RuleIds=@RuleIds+','+(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=@rulescheduleid)))
-- 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
答案 3 :(得分:0)
就个人而言,我根本不会使用光标。我会在select中使用CASE
语句来获取要发送回应用程序的字段并返回整个数据集。然后我将循环应用程序端的数据集,以根据应用程序的需要设置参数值。