Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Msg 266: Previous count = 1, current count = 0. как бороться?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
у меня точно такая ситуация, только процедуры длинее.
Пишут, что мол 266 сообщение - это не ошибка, а предупреждение.
Хорошо, как избавиться, задавить его?

CREATE PROC SP_A
AS

DECLARE @Ok int

BEGIN TRAN

EXEC @Ok = SP_B

IF @@ERROR <> 0 OR @Ok < 0
BEGIN
RAISERROR ('Error in SP_B!', 16, 1)

IF @@TRANCOUNT <> 0
BEGIN
ROLLBACK TRAN
END

RETURN -100
END

COMMIT TRAN

RETURN 0

------------------------------------------------
GO

CREATE PROC SP_B
AS

DECLARE @n int

BEGIN TRAN

SET @n = 1

IF @n = 1
BEGIN
ROLLBACK TRAN
RETURN -1
END

COMMIT TRAN

RETURN 0


If you try to execute SP_A you'll get the following
error:

Server: Msg 266, Level 16, State 2, Line 0
Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION
statement is missing. Previous count = 1, current count = 0.
Server: Msg 50000, Level 16, State 1, Procedure SP_A, Line 12
Error in SP_B!
22 апр 09, 14:55    [7098959]     Ответить | Цитировать Сообщить модератору
 Re: Msg 266: Previous count = 1, current count = 0. как бороться?  [new]
Glory
Member

Откуда:
Сообщений: 104760
Нужно проверять во вложенной процедуре наличие транзакции
22 апр 09, 15:56    [7099532]     Ответить | Цитировать Сообщить модератору
 Re: Msg 266: Previous count = 1, current count = 0. как бороться?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
Glory
Нужно проверять во вложенной процедуре наличие транзакции


это я хотел пример проще сделать, поспешил, а реально во внутренней процедуре я не открываю транзакцию, а только закрываю внешнюю. И вот из-за того, что в точке вызова перед вызовом и непосредственно после переменная @@TRANCOUNT имеет разные значения - получаю это сообщение

те. приблизительно так:

CREATE PROC SP_A
AS

DECLARE @Ok int

BEGIN TRAN

EXEC @Ok = SP_B

IF @@ERROR <> 0 OR @Ok < 0
BEGIN
RAISERROR ('Error in SP_B!', 16, 1)

IF @@TRANCOUNT <> 0
BEGIN
ROLLBACK TRAN
END

RETURN -100
END

COMMIT TRAN

RETURN 0

------------------------------------------------
GO

CREATE PROC SP_B
AS

DECLARE @n int

-- BEGIN TRAN

SET @n = 1

IF @n = 1
BEGIN
ROLLBACK TRAN
RETURN -1
END

COMMIT TRAN

RETURN 0


If you try to execute SP_A you'll get the following
error:

Server: Msg 266, Level 16, State 2, Line 0
Transaction count after EXECUTE indicates that a COMMIT or ROLLBACK TRANSACTION
statement is missing. Previous count = 1, current count = 0.
Server: Msg 50000, Level 16, State 1, Procedure SP_A, Line 12
Error in SP_B!
22 апр 09, 17:17    [7100291]     Ответить | Цитировать Сообщить модератору
 Re: Msg 266: Previous count = 1, current count = 0. как бороться?  [new]
san_d
Member

Откуда: Киев
Сообщений: 60
вопрос по этой же ошибке..
SQL Server 2000 SP 4

ограничение понятно.
У меня есть несколько процедур, которые могут вызываться как отдельно, так и из других процедур. Поэтому транзакцию нужно начинать в каждой процедуре.

Почитал примеры как это обходить, которые даются в БОЛе, мне так не совсем подходит в моем конкретном случае(конечно, можно сделать и по такому принципу, но переписывать теперь кучу всего:)).
Сделал по-другому, хочу теперь спросить нормальный ли это подход:)
В каждой процедуре поставил что-то типо такого
declare @tranHere int

if @@trancount <> 0 begin
  set @tranHere = 1
  begin tran
end


--тут делаем что-то с данными

if @tranHere = 1
  if @@trancount <> 0 commit tran
Вроде все работает, но может это неправильно так писать?
14 авг 09, 15:27    [7540206]     Ответить | Цитировать Сообщить модератору
 Re: Msg 266: Previous count = 1, current count = 0. как бороться?  [new]
san_d
Member

Откуда: Киев
Сообщений: 60
упс if @@trancount = 0 begin
declare @tranHere int

if @@trancount = 0 begin
  set @tranHere = 1
  begin tran
end


--тут делаем что-то с данными

if @tranHere = 1
  if @@trancount <> 0 commit tran

14 авг 09, 16:53    [7540898]     Ответить | Цитировать Сообщить модератору
 Re: Msg 266: Previous count = 1, current count = 0. как бороться?  [new]
Кудряшка
Member

Откуда: Сидней
Сообщений: 2219
В деталях не читала, но что бросилось в глаза... ROLLBACK откатывает все открытые транзакции в текушей сессии.
Повторный ROLLBACK или попытка COMMIT ошибку.

Везде, перед ROLLBACK в процедурах (всех) делайте проверку на

IF @@TRANCOUNT <> 0
ROLLBACK TRAN
14 авг 09, 17:32    [7541100]     Ответить | Цитировать Сообщить модератору
 Re: Msg 266: Previous count = 1, current count = 0. как бороться?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31170
san_d
Вроде все работает, но может это неправильно так писать?
Да, так и надо делать.
16 авг 09, 19:05    [7543807]     Ответить | Цитировать Сообщить модератору
 Re: Msg 266: Previous count = 1, current count = 0. как бороться?  [new]
Crimean
Member

Откуда:
Сообщений: 13148
имхо толкового решения этой проблемы так и не нашел никто
мы применяем сейвпоинты, но от них много головной боли, зато уверенность, что
1) не будет этого сообщения
2) ошибка разработчика - пропуск обработки ошибок - не развалит базу
17 авг 09, 14:17    [7546441]     Ответить | Цитировать Сообщить модератору
 Re: Msg 266: Previous count = 1, current count = 0. как бороться?  [new]
Crimean
Member

Откуда:
Сообщений: 13148
2 san_d

> В каждой процедуре поставил что-то типо такого

в вашем случае если "внешняя" процедура проигнорирует ошибку "внутренней", то база будет "разрушена" в результате такого поведения. потому как "внутренняя" должна была бы "откатить" свои действия, но в вашем варианте она не управляет транзакциями

то есть подход, конечно, работать будет, но будет достаточно чуствителен к "опискам" в коде
18 авг 09, 11:56    [7550426]     Ответить | Цитировать Сообщить модератору
 Re: Msg 266: Previous count = 1, current count = 0. как бороться?  [new]
ветерочек
Member

Откуда: СПБ
Сообщений: 153
Crimean
2 san_d

> В каждой процедуре поставил что-то типо такого

в вашем случае если "внешняя" процедура проигнорирует ошибку "внутренней", то база будет "разрушена" в результате такого поведения. потому как "внутренняя" должна была бы "откатить" свои действия, но в вашем варианте она не управляет транзакциями

то есть подход, конечно, работать будет, но будет достаточно чуствителен к "опискам" в коде


внутренняя и не должна откатывать внешнюю
и естественно нужно обрабатывать результат каждой внутренней процедуры

я так делаю
18 авг 09, 12:03    [7550483]     Ответить | Цитировать Сообщить модератору
 Re: Msg 266: Previous count = 1, current count = 0. как бороться?  [new]
ветерочек
Member

Откуда: СПБ
Сообщений: 153
проглядел что 2000 сервер , там было сложнее .
18 авг 09, 12:04    [7550504]     Ответить | Цитировать Сообщить модератору
 Re: Msg 266: Previous count = 1, current count = 0. как бороться?  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
ветерочек
Crimean
2 san_d

> В каждой процедуре поставил что-то типо такого

в вашем случае если "внешняя" процедура проигнорирует ошибку "внутренней", то база будет "разрушена" в результате такого поведения. потому как "внутренняя" должна была бы "откатить" свои действия, но в вашем варианте она не управляет транзакциями

то есть подход, конечно, работать будет, но будет достаточно чуствителен к "опискам" в коде


внутренняя и не должна откатывать внешнюю
и естественно нужно обрабатывать результат каждой внутренней процедуры

я так делаю



забыли дописать: "если это возможно", потому что, если невозможно - у внутренней есть только один выход - откат по самое не могу...
18 авг 09, 12:15    [7550602]     Ответить | Цитировать Сообщить модератору
 Re: Msg 266: Previous count = 1, current count = 0. как бороться?  [new]
san_d
Member

Откуда: Киев
Сообщений: 60
Crimean
2 san_d

> В каждой процедуре поставил что-то типо такого

в вашем случае если "внешняя" процедура проигнорирует ошибку "внутренней", то база будет "разрушена" в результате такого поведения. потому как "внутренняя" должна была бы "откатить" свои действия, но в вашем варианте она не управляет транзакциями

то есть подход, конечно, работать будет, но будет достаточно чуствителен к "опискам" в коде

да, это сделал. Каждая процедура возвращает результат(int), внешняя коммитит только, если во внутренней не было ошибки.
Т.е., упрощенно, как-то так
declare @err int,@tranHere int
           
if @@trancount = 0 begin
  set @tranHere = 1
  begin tran
end

exec @err = sp_myInnerSP
if @err <> 0 goto exit_err

if @tranHere = 1
 if @@trancount <> 0 commit tran
return (@err)

exit_err:
if @tranHere = 1 begin
  if @@trancount <> 0 rollback tran
end
return(@err)

конечно, может чего-то не учел, сейчас тестирую. Буду разбираться с сейвпойнтами, но уже в следующем проэкте:)
18 авг 09, 13:20    [7551033]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить