2010-12-14 3 views
0

Мне нужно написать хранимую процедуру, в которой вы указываете месяц, номер кредитной карты, и она вычисляет 1% для каждой транзакции, сделанной в первые 10 дней месяца, 2% для транзакции между 10 и 20 и 3% для транзакций выше 20. И я должен использовать курсоры.помощь, хранимые процедуры и курсоры

я писал этот код, но я получаю некоторые ошибки, когда я пытаюсь запустить 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 to int не допускается.

спасибо :) i теперь освободите курсор в конце хранимой процедуры и удалили день(). Теперь я хочу напечатать pos + pos2 + pos3. Я использую print 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

+0

Я также хочу указать, что float является плохим выбором, если вы хотите получить математическую точность. Вы можете в своих собственных целях попытаться перезаписать это, используя оператор case вместо курсора. – HLGEM

ответ

1

Да, вам необходимо освободить курсор после его закрытия. Кроме того, если ваш запрос имел ошибку перед закрытием курсора, он, возможно, остался открытым, поэтому я рекомендую вам выполнить CLOSE и DEALLOCATE перед выполнением вашей процедуры еще раз. Для вашей второй ошибки вы используете функцию DAY() по переменной типа INT, смените if day(@mera)<=10 на if @mera<=10. Обновление: Теперь, когда вы исправили проблемы, которые у вас были, когда вы добавляете каждую переменную @pos, следуя вашей логике, один из них всегда равен нулю, поэтому вы должны добавить их следующим образом: Печать isnull (@ pos1,0) + isnull (@ pos2,0) + isnull (@ pos3,0)

+0

Большое вам спасибо за помощь мне :) – George

3

Другие предложили использовать DEALLOCATE. Проблема в том, что в некоторых случаях ошибки он не будет вызван. Если вы затем попытаетесь использовать одно и то же соединение для вызова этого сохраненного proc, курсор все равно будет выделен.

Я бы предпочел вместо этого declare the cursor as LOCAL, что означает, что он автоматически освобождается при выходе из хранимой процедуры (как обычно, так и без нее).

Смежные вопросы