Sql server 2005 使用游标时SQL Server过程中变量的范围

Sql server 2005 使用游标时SQL Server过程中变量的范围,sql-server-2005,Sql Server 2005,我试图将从DB检索到的数据存储到一个变量中,并将其返回到java代码中 它正在返回空值。这是因为游标中变量的范围。有人能提出解决办法吗 以下是我的程序: ALTER PROCEDURE [dbo].[rml_ups_profilerscheduler] @RuleIds varchar(200) output -- Add the parameters for the stored procedure here --<@Param1, sysname, @p1> &l

我试图将从DB检索到的数据存储到一个变量中,并将其返回到java代码中

它正在返回空值。这是因为游标中变量的范围。有人能提出解决办法吗

以下是我的程序:

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
此位:

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

 FETCH NEXT FROM cursorName
 INTO @rulescheduleid, @scheduletype
绝对是错误的-@@FETCH\u状态根据上一个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结果


话虽如此,我还没有通读代码墙的其余部分来了解您正在尝试做什么以及是否需要光标。

基本上,您的光标是这样组织的:

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
open cursor

fetch first row into vars

while @@fetch_status = 0

  process the fetched values
  fetch next row into vars

end
现在,获取值部分的过程在您的过程中相当重要,并且在代码中重复两次,这是一回事。另一个更重要的事情是,当您在循环体中处理获取的值时,实际上是在获取值之后立即执行。但是,如果是最后一次迭代,它将获取NULL,并且作为处理NULL的结果,输出变量也将返回NULL

那么,在这种情况下你应该怎么做?只需将进程“获取的值”阶段放在循环之前,并将另一个(在获取下一行之后)移动到vars步骤之前的位置,以便光标的结构如下所示:

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
open cursor

fetch first row into vars

while @@fetch_status = 0

  process the fetched values
  fetch next row into vars

end
这样,您只有一个处理值的位置,并且只有在值不为NULL时才进行处理,因为一旦下一次获取产生NULL,您就退出循环,保留累积的输出

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= 声明@ruleId 声明cName游标 对于 选择不同的id、stype 来自表1 打开光标名称-打开光标 从cName获取下一个 进入@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 

就我个人而言,我根本不会使用光标。我会在select中使用CASE语句来获取要发送回应用程序的字段,并返回整个数据集。然后,我将在应用程序端循环遍历数据集,以根据应用程序的需要设置参数值

关于是否需要光标的好观点,总是值得一提,+1.我修改了我的代码过程运行时没有任何错误,但在循环结束时,根据条件从db获取的值指定给变量在循环完成后变为空。这里是我修改的代码。我修改了我的代码过程运行时没有任何错误,但在循环结束时,根据条件从db获取的值变为空循环完成后,指定给变量的条件变为空此处是我修改的代码我修改了我的代码过程正在运行,没有任何错误,但在循环结束时,根据指定给变量的条件从db中获取的值在循环完成后变为空此处是我修改的代码我已粘贴我的修改后的代码这是一个基于问答的网站-这不是答案-你应该,相反,编辑你的问题,添加新的信息。另外,请注意,上面的格式设置相当糟糕——请尝试使用格式设置工具,并对您的问题进行适当的编辑。