关于sql server:help、存储过程和游标

help, stored procedures and cursors

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

我写了这段代码,但是当我尝试运行程序时遇到了一些错误

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
   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 cc_number=@cardNo and month([DateTime])=@minas

/* 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 cc_number=@cardNo and month([DateTime])=@minas )
/* get 1st row*/
fetch sinallages into @karta,@mera,@poso
while (/*@@sqlstatus != 2*/@counter<@count)
  begin
    if day(@mera)<=10
    set @pos =@poso+ @poso * 0.01
    else
    if day(@mera)>10 and day(@mera)<=20
    set @pos2 =@poso+ @poso * 0.02
    else
    if day(@mera) > 20
    set @pos3 =@poso+ @poso * 0.03
    fetch sinallages into @karta,@mera,@poso
  set @counter=@counter+1
  end

close sinallages

return

当我调用程序时,我得到

EXEC cardP @minas = 5, @cardNo =4929569752542450

1
2
3
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

Cursor Fetch:不允许从数据类型 datetime 到 int 的隐式转换。

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

1
2
3
4
5
6
7
8
9
10
    ................
      set @counter=@counter+1
  end
print @pos+@pos2+@pos3
close sinallages



return
DEALLOCATE sinallages;

似乎 hte 变量 po,pos2,pos3 为空??


其他人建议使用 DEALLOCATE。问题在于,在某些错误情况下,它不会被调用。如果您随后尝试使用相同的连接来调用此存储过程,游标仍将被分配。

我更愿意将游标声明为 LOCAL,这意味着它会在存储过程退出时自动释放(无论是否正常)。


是的,您需要在关闭游标后释放游标。此外,如果您的查询在关闭游标之前出现错误,它可能一直处于打开状态,因此我建议您在再次执行过程之前执行 CLOSEDEALLOCATE。对于第二个错误,您在 INT 类型的变量上使用函数 DAY(),将 if day(@mera)<=10 更改为 if @mera<=10
更新:既然您解决了您遇到的问题,当您添加每个 @pos 变量时,按照您的逻辑,其中一个始终为空,因此您应该像这样添加它们:
打印 isnull(@pos1,0) isnull(@pos2,0) isnull(@pos3,0)


之后

1
close sinallages

你需要调用

1
deallocate sinallages

看看 DEALLOCATE (Transact-SQL)


你必须在关闭光标后释放它:

1
DEALLOCATE sinallages

http://msdn.microsoft.com/en-us/library/ms188782.aspx