Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Вызов процедур внутри процедуры-обертки  [new]
Alex Zhulin
Member

Откуда:
Сообщений: 56
Добрый день!

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

Процедура создания клиента:

ALTER PROCEDURE [dbo].[import_infocraft_load_client]
(
	@family_name	varchar(100)
	, @first_name	varchar(100)
	, @fathers_name	varchar(100)
	, @gender_id	integer
	, @out_client_id	integer OUT
)
WITH EXECUTE AS 'dbo'
AS
BEGIN
	declare @client_id integer;
	-- Сгенерируем новый идентификатор клиента
	insert into pes_clients DEFAULT VALUES;
	-- Вернем его в переменную
	select @client_id = SCOPE_IDENTITY();
	-- Заполним доп информацию по клиенту
	insert into pes_individuals
	(client_id, family_name, first_name, fathers_name, gender_id)
	values
	(@client_id, @family_name, @first_name, @fathers_name, @gender_id);
	-- Вернем сгенерированный идентификатор клиента
	select @out_client_id = @client_id;
END


Процедура создания договора

ALTER PROCEDURE [dbo].[import_infocraft_load_account]
(
	@client_id integer
	, @account_number_base	nvarchar(100)
	, @account_number_electro	nvarchar(100)
	, @out_account_id	integer OUT
)
WITH EXECUTE AS 'dbo'
AS
BEGIN
	declare @base_number_type integer = 1; -- Тип счета за ЖКХ
	declare @electro_number_type integer = 2; -- Тип счета за электричество
	declare @account_id integer;
	-- Сгенерируем новый идентификатор договора
	insert into pes_accounts
	(client_id)
	values
	(@client_id);
	-- Вернем его в переменную
	select @account_id = SCOPE_IDENTITY();
	-- Добавим номера счетов
	insert into pes_account_numbers
	(account_id, account_number_type_id, account_number)
	values
	(@account_id, @base_number_type, @account_number_base);
	--
	insert into pes_account_numbers
	(account_id, account_number_type_id, account_number)
	values
	(@account_id, @electro_number_type, @account_number_electro);
	--
	select @out_account_id = @account_id
	--
	--return @out_account_id;
END


Вот процедура-обертка, которая вызывает их обоих:

ALTER PROCEDURE [dbo].[import_infocraft_load_all]
(
	@family_name	varchar(100)
	, @first_name	varchar(100)
	, @fathers_name	varchar(100)
	, @gender_id	integer
	, @account_number_base	nvarchar(100)
	, @account_number_electro	nvarchar(100)
	, @out_account_id	integer OUT
)
WITH EXECUTE AS 'dbo'
AS
BEGIN
	begin try
		begin transaction
			declare @client_id integer;
			-- Создадим клиента
			exec import_infocraft_load_client @family_name, @first_name, @fathers_name, @gender_id, @client_id; 
			-- Создадим договор
			exec import_infocraft_load_account @client_id, @account_number_base, @account_number_electro, @out_account_id 
		commit transaction
	end try
	begin catch
		if @@TRANCOUNT > 0
			ROLLBACK TRAN --RollBack in case of Error
		
		DECLARE @ErrorMessage NVARCHAR(4000);
		DECLARE @ErrorSeverity INT;
		DECLARE @ErrorState INT;
		--
		SELECT 
			@ErrorMessage = ERROR_MESSAGE(),
			@ErrorSeverity = ERROR_SEVERITY(),
			@ErrorState = ERROR_STATE();
		--
		RAISERROR (@ErrorMessage, -- Message text.
				   @ErrorSeverity, -- Severity.
				   @ErrorState -- State.
				   );
	end catch
END


При вызове

declare @test integer;
exec import_infocraft_load_all 'test_family_name', 'test_first_name', 'test_fathers_name', 0, '123', '456', @test


Получаю ошибку

Сообщение 50000, уровень 16, состояние 2, процедура import_infocraft_load_all, строка 38
Не удалось вставить значение NULL в столбец "client_id", таблицы "PES_TestBD.dbo.pes_accounts"; в столбце запрещены значения NULL. Ошибка в INSERT.

Т.е. после вызова первой процедуры

-- Создадим клиента
exec import_infocraft_load_client @family_name, @first_name, @fathers_name, @gender_id, @client_id;
-- Создадим договор
exec import_infocraft_load_account @client_id, @account_number_base, @account_number_electro, @out_account_id

в переменную @client_id не вернулся идентификатор клиента и как следствие не передался во вторую процедуру.
Подскажите, в чем моя ошибка.

Спасибо.
8 окт 13, 14:10    [14939679]     Ответить | Цитировать Сообщить модератору
 Re: Вызов процедур внутри процедуры-обертки  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
если нужно, чтобы возвращался @client_id, тогад надо сделать его в первой процедуре output в объявлении и при вызове

exec import_infocraft_load_client @family_name, @first_name, @fathers_name, @gender_id, @client_id;
8 окт 13, 14:14    [14939706]     Ответить | Цитировать Сообщить модератору
 Re: Вызов процедур внутри процедуры-обертки  [new]
Alex Zhulin
Member

Откуда:
Сообщений: 56
Вроде ведь так и сделал

ALTER PROCEDURE [dbo].[import_infocraft_load_client]
(
@family_name varchar(100)
, @first_name varchar(100)
, @fathers_name varchar(100)
, @gender_id integer
, @out_client_id integer OUT
)
8 окт 13, 14:17    [14939726]     Ответить | Цитировать Сообщить модератору
 Re: Вызов процедур внутри процедуры-обертки  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Alex Zhulin,

вам про указание OUT в вызове процедуры говорили (но не договорили :-))

exec import_infocraft_load_client @family_name, @first_name, @fathers_name, @gender_id, @client_id OUT; 
8 окт 13, 14:19    [14939749]     Ответить | Цитировать Сообщить модератору
 Re: Вызов процедур внутри процедуры-обертки  [new]
Alex Zhulin
Member

Откуда:
Сообщений: 56
Спасибо БОЛЬШОЕ!
Получилось

tpg
Alex Zhulin,

вам про указание OUT в вызове процедуры говорили (но не договорили :-))

exec import_infocraft_load_client @family_name, @first_name, @fathers_name, @gender_id, @client_id OUT; 
8 окт 13, 14:22    [14939772]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить