【问题标题】:Sql Server - Cursor not working in stored procedureSql Server - 游标在存储过程中不起作用
【发布时间】:2014-08-23 02:15:51
【问题描述】:

我正在使用 AdventureWorks ( Sql server 2005 express) 并想通过以下 SP 了解哪个性别的休假时间最长。 SP 编译良好,但执行时未显示任何结果

这里是sp

create proc GenderLeaveCount
as
begin
declare @gender nchar(1)
declare @leaveHours smallint

declare @totalHoursMale int
declare @totalHoursFemale int

declare genderLeave Cursor
for select Gender , SickLeaveHours
from HumanResources.Employee
where SickLeaveHours is not null and Gender is not null


open genderLeave

fetch next from genderLeave 
into @gender,@leaveHours

while @@fetch_status=0
Begin
    IF @gender = N'M'
        Set @totalHoursMale = @totalHoursMale + @leaveHours
    ELSE
        Set @totalHoursFemale = @totalHoursFemale + @leaveHours

    fetch next from genderLeave 
    into @gender,@leaveHours

End

close genderLeave
deallocate genderLeave

IF @totalHoursMale > @totalHoursFemale
    Select 'Male leave hours are higher:' + cast(@totalHoursMale as varchar(20))as result
IF @totalHoursMale < @totalHoursFemale
    Select 'Male leave hours are higher:' + cast(@totalHoursMale as varchar(20))as result
IF @totalHoursMale = @totalHoursFemale
    Select 'Male leave hours are higher:' + cast(@totalHoursMale as varchar(20)) as result

end
go
exec GenderLeaveCount

谁能告诉我问题是什么以及如何解决它..

【问题讨论】:

  • 您需要使@totalHoursMale@totalHoursFemale 等于0。这不是VBScript,其中未初始化的变量在稍后被引用时通过魔术设置为0。现在您正在添加等于NULLNULL + @leaveHours,所以没有什么要打印的,因为当您将NULL 连接到您的字符串时,这也会产生NULL。无论如何,只是SELECT Gender, SUM(LeaveHours) ... GROUP BY Gender;然后在客户端打印条件消息不是更有效吗?
  • @AsheshKumar 我真的不明白这是怎么重复的。
  • (哦,调试 101,SELECT 循环中的变量...)

标签: sql-server stored-procedures cursor


【解决方案1】:

谢谢亚伦·伯特兰..

:)

.net 所有变量的默认值为 0...我想知道为什么 MS 没有给 sql server 变量提供默认值..

我进行了初始化,现在它可以工作了..有时我在 fetch 和其他语法中迷失了方向,而没有注意到这些微小的代码错误。我正在使用这个 sp 向我的学生演示如何使用带有 while 语句的游标,我知道它不是最好的例子,我也可以使用 TVF。 这是合并更改后的灵魂。

create proc GenderLeaveCount
as
begin
declare @gender nchar(1)
declare @leaveHours smallint

declare @totalHoursMale int
declare @totalHoursFemale int

set @totalHoursMale = 0
set @totalHoursFemale = 0

declare genderLeave Cursor
for select Gender , SickLeaveHours
from HumanResources.Employee
where SickLeaveHours is not null and Gender is not null


open genderLeave

fetch next from genderLeave 
into @gender,@leaveHours

while @@fetch_status=0
Begin
    IF @gender = N'M'
        Set @totalHoursMale = @totalHoursMale + @leaveHours
    ELSE
        Set @totalHoursFemale = @totalHoursFemale + @leaveHours

    fetch next from genderLeave 
    into @gender,@leaveHours

End

close genderLeave
deallocate genderLeave

IF @totalHoursMale > @totalHoursFemale
    Select 'Male leave hours are higher:' + cast(@totalHoursMale as varchar(20))as result
IF @totalHoursMale < @totalHoursFemale
    Select 'Female leave hours are higher:' + cast(@totalHoursMale as varchar(20))as result
IF @totalHoursMale = @totalHoursFemale
    Select 'Male and Female Leave hours are equal:' + cast(@totalHoursMale as varchar(20)) as result
end

【讨论】:

  • 因为 SQL Server 早在 .NET 的出现之前就已经存在多年了?另外,您是在谈论经典的VB吗?我很确定 .net 具有可为空的变量,其中所有未实例化的变量都不会神奇地变为 0。shrug SQL Server 的做法是正确的。
【解决方案2】:

您可以在查询中使用以下查询而不是光标: 游标的性能低于以下查询:

SELECT CASE 
        WHEN [M]>[F] THEN 'Male leave hours are higher:' + cast(@M as varchar(20))
        WHEN [M]<[F] THEN 'Male leave hours are higher:' + cast(@M as varchar(20))
        WHEN [M]=[F] THEN 'Male leave hours are higher:' + cast(@M as varchar(20))
    END as result
FROM (SELECT Gender, SUM(SickLeaveHours) AS TotalHours
    FROM HumanResources.Employee
    WHERE SickLeaveHours is not null and Gender is not null
    GROUP BY Gender
    )p
PIVOT ( SUM(TotalHours) FOR Gender IN ([M],[F]))pvt

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-12
    • 2015-07-03
    • 1970-01-01
    • 2023-03-04
    相关资源
    最近更新 更多