помощь, хранимые процедуры и курсоры - PullRequest
0 голосов
/ 14 декабря 2010

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

я написал этот код, но я получаю некоторые ошибки, когда пытаюсь запустить предварительную процедуру

   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

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 недопустимо.

спасибо :) теперь я освободил курсор в конце хранимой процедуры и удалил день (). Теперь я хочу напечатать pos + pos2 + pos3. Я использую print pos + pos2 + pos3, но он ничего не печатает. это почему ??

    ................
      set @counter=@counter+1
  end
print @pos+@pos2+@pos3
close sinallages



return 
DEALLOCATE sinallages;

похоже, что переменные po, pos2, pos3 остаются нулевыми ??

Ответы [ 4 ]

3 голосов
/ 14 декабря 2010

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

Я бы предпочел вместо объявить курсор как LOCAL , что означает, что он автоматически освобождается при выходе из сохраненного процесса (как обычно, так и нет).

1 голос
/ 14 декабря 2010

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

1 голос
/ 14 декабря 2010

После

close sinallages 

Вам нужно позвонить

deallocate sinallages 

Посмотрите на DEALLOCATE (Transact-SQL)

0 голосов
/ 14 декабря 2010

Вы должны освободить курсор после его закрытия:

DEALLOCATE sinallages

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

...