2010-12-14 88 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退出時(無論是否正常)它會自動釋放。