2010-12-14 89 views
0

我必须编写一个存储过程,在这里给出月份和一个信用卡号,它为本月前10天的每笔交易计算1%,为2%计算交易在10到20之间,交易在20以上时为3%。 我必须使用游标。帮助,存储过程和游标

我写了这个代码,但我得到了一些错误,当我尝试运行precedure

create procedure cardP 
    /* month ex 1,3,5 etc*/ 
    @minas int, 
    @cardNo bigint 



as 
/* creating the cursor*/ 
DECLARE sinallages CURSOR 
FOR SELECT cc_number,day([DateTime]),charged_amount FROM transactions 
where [email protected] and month([DateTime])[email protected] 

/* declaring local variables*/ 
declare @poso int,@karta bigint,@mera int,@pos float,@pos2 float,@pos3 float, 
@count int,@counter int 

open sinallages 



set @count=(select count(cc_number) from transactions where [email protected] and month([DateTime])[email protected]) 
/* get 1st row*/ 
fetch sinallages into @karta,@mera,@poso 
while (/*@@sqlstatus != 2*/@counter<@count) 
    begin 
    if day(@mera)<=10 
    set @pos [email protected]+ @poso * 0.01 
    else 
    if day(@mera)>10 and day(@mera)<=20 
    set @pos2 [email protected]+ @poso * 0.02 
    else 
    if day(@mera) > 20 
    set @pos3 [email protected]+ @poso * 0.03 
    fetch sinallages into @karta,@mera,@poso 
    set @[email protected]+1 
    end 

close sinallages 

return 

当我调用过程我得到

EXEC cardP @minas = 5,@cardNo = 4929569752542450

Msg 16915, Level 16, State 1, Procedure cardP, Line 20 
A cursor with the name 'sinallages' already exists. 
Msg 16922, Level 16, State 1, Procedure cardP, Line 31 

游标提取:从数据类型的DAT隐式转换不允许将etime转换为int。

谢谢:)我现在在存储过程结束时取消分配游标并删除了day()。现在我想打印pos + pos2 + pos3。我使用打印pos + pos2 + pos3但它不打印任何东西。这是为什么 ??

................ 
     set @[email protected]+1 
    end 
print @[email protected][email protected] 
close sinallages 



return 
DEALLOCATE sinallages; 

它似乎像hte变量po,pos2,pos3是空的?? ??

+1

我意识到这是家庭作业,你必须使用游标,但你应该明白游标不是你通常想要写入生产代码的东西。就我个人而言,除了想要成为dbas的高级人士之外,我根本不会考虑教导游标。请看看这个链接:http://wiki.lessthandot.com/index.php/Cursors_and_How_to_Avoid_Them – HLGEM 2010-12-14 14:30:18

+0

我也想指出,如果你想要数学的准确性,float是一个糟糕的选择。您可能为了您自己的学习目的尝试使用case语句而不是光标来重写此语句。 – HLGEM 2010-12-14 14:31:55

回答

1

是的,你需要在关闭它之后释放光标。另外,如果你的查询在关闭游标之前有错误,它可能保持打开,所以我建议你在再次执行你的程序之前执行CLOSEDEALLOCATE。对于第二个错误,您正在使用函数DAY()而不是INT类型的变量,请使用if @mera<=10更改if day(@mera)<=10更新:现在您已解决了您遇到的问题,当您添加每个@pos变量时,遵循您的逻辑,其中一个始终为空,因此您应该像这样添加它们: Print isnull(@ pos1,0) + isnull(@ pos2,0)+ isnull(@ pos3,0)

+0

非常感谢你帮助我:) – George 2010-12-15 18:16:12

3

其他人建议使用DEALLOCATE。问题在于,在某些错误情况下,它不会被调用。如果你尝试使用同一个连接来调用这个存储过程,游标仍然会被分配。

我宁愿改为declare the cursor as LOCAL,这意味着当存储的proc退出时(无论是否正常)它会自动释放。