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

Откуда: Moscow
Сообщений: 907
Привет. Подскажите по сабжу.
Имеется две таблицы:
Main
Child


Для вставки в main имеется процедура

Create procedure [dbo].[MainInsert]
		 @Title nvarchar(max)
as
	begin
		set nocount on
		[dbo].[Main]
		(
			[Title]	
		) 
		values 
		(
			@Title 
		)
		select cast(scope_identity() as int) AS [scope_identity];
	end


Как можно написать скрипт инициализационный скрипт, который вставляет в Main таблицу, получает scope_identity и вставляет в child таблицу

Пробую так:

  declare @MainId int
  --set @MainId = [dbo].[MainInsert] (N'test1')
  --exec @MainId = [dbo].[MainInsert] (N'test1')
  
  select @MainId 


но получаю

  Msg 102, Level 15, State 1, Line 18
  Incorrect syntax near 'test1'


Что то никак не могу нагуглить как вызывать процедуру и получать результат scope_identity из нее

Или в t-sql такое не работает ? Ведь на клиенте то я могу получить результат этого селекта !!
26 янв 16, 19:22    [18732460]     Ответить | Цитировать Сообщить модератору
 Re: Как написать инициализационный скрипт t-sql ?  [new]
komrad
Member

Откуда:
Сообщений: 5252
ProBiotek,

create table Main (i int identity, title nvarchar(50))
create table Child (i int identity, main_id int)
go

create proc MainInsert 
	@title nvarchar(50),
	@output int output
as
	begin
		insert into Main (title) values (@title)
		select @output=scope_identity()
	end
go
declare @id int
exec MainInsert 'Hello',@output=@id output
insert into Child (main_id) values (@id)
go

select * from Main
select * from Child 
go
26 янв 16, 19:39    [18732507]     Ответить | Цитировать Сообщить модератору
 Re: Как написать инициализационный скрипт t-sql ?  [new]
Glory
Member

Откуда:
Сообщений: 104760
ProBiotek
Что то никак не могу нагуглить как вызывать процедуру

Вы хелп по команде EXEC не пробовали читать ?
Вот просто окрыть статью и прочитать до конца ?
27 янв 16, 10:19    [18734338]     Ответить | Цитировать Сообщить модератору
 Re: Как написать инициализационный скрипт t-sql ?  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
Я искал способ без Output просто. Наверное стоило это упомянуть.
Просто я не могу изменить существующую процедуру...

Вообще мне интересно, объясните пожалуйста. Почему с клиентской стороны можно получить данные из процедуры,схватив ее Селект, а из другой процедуры нельзя. Я думал что это тоже возможно - и искал этот вариант.
27 янв 16, 11:41    [18734795]     Ответить | Цитировать Сообщить модератору
 Re: Как написать инициализационный скрипт t-sql ?  [new]
Glory
Member

Откуда:
Сообщений: 104760
ProBiotek
Почему с клиентской стороны можно получить данные из процедуры,схватив ее Селект, а из другой процедуры нельзя.

Потому, что клиент и сервер - это две разные вещи. А не одна, как вы думаете.
Если вы указали серверу возвращать данные клиенту, то с чего вдруг он должен "хватать селект" себе.
27 янв 16, 11:44    [18734817]     Ответить | Цитировать Сообщить модератору
 Re: Как написать инициализационный скрипт t-sql ?  [new]
DaniilSeryi
Member

Откуда:
Сообщений: 1741
Во-первых, в процедуру вставьте пропущенную строку insert into:

Create procedure [dbo].[MainInsert]
		 @Title nvarchar(max)
as
	begin
		set nocount on
                [b]insert into[/b] 	[dbo].[Main]
		(
			[Title]	
		) 
		values 
		(
			@Title 
		)
		select cast(scope_identity() as int) AS [scope_identity];
	end


Во-вторых, в таблице dbo.Main должно быть identity-поле;

В-третьих, при выполнении этих двух условий сделайте так:

select *
from dbo.Main

declare @Title nvarchar(max)='1234'

declare @table_variable table (ID int)
insert @table_variable exec [dbo].[Maininsert] @Title
select MAX(id) as Ne_Identity from @table_variable
select *
from dbo.Main


select * from dbo.Main - для контроля вставки данных
, @Title - данные для вставки
,@table_variable - табличная переменная, куда вставляем итог select-a в процедуре
, MAX(id) - чтобы получить из всего столбца табличной переменной одно число.
27 янв 16, 12:40    [18735216]     Ответить | Цитировать Сообщить модератору
 Re: Как написать инициализационный скрипт t-sql ?  [new]
DaniilSeryi
Member

Откуда:
Сообщений: 1741
и - глюк обработки bb-кодов.
27 янв 16, 12:41    [18735224]     Ответить | Цитировать Сообщить модератору
 Re: Как написать инициализационный скрипт t-sql ?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31438
ProBiotek
Вообще мне интересно, объясните пожалуйста. Почему с клиентской стороны можно получить данные из процедуры,схватив ее Селект, а из другой процедуры нельзя.
Да просто - так сделано. Объяснений, почему такое решение правильное, и какие преимущества даёт разработчикам, нет. Или, точнее, есть одно - я слышал такое объяснение - что бы труднее было реализовывать логику на стороне СУБД. Что бы её выносили на сторону клиента (сервера приложений).

ProBiotek
Я думал что это тоже возможно - и искал этот вариант.
Этот вариант есть:
INSERT таблица
EXEC процедура
Но он неудобен, обладает многочисленными недостатками и ограничениями, так что его лучше не использовать.

Возвращайте скалярные значения через output.

А вместо возврата наборов данных проектируйте (и бизнес-логику) систему так, что бы обработка была многостадийной, с сохранением результатов в постоянных таблицах.
Ещё вариант - "переворачивать" цепочку вызовов, то есть из клиента должны вызываться процедуры нижнего уровня, расчётные, а они уже должны вызывать процедуры, формирующие итоговый результат для клиента - и тогда передавать данные от первых во вторые можно через табличные параметры.
27 янв 16, 13:02    [18735345]     Ответить | Цитировать Сообщить модератору
 Re: Как написать инициализационный скрипт t-sql ?  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
DaniilSeryi
select *
from dbo.Main

declare @Title nvarchar(max)='1234'

declare @table_variable table (ID int)
insert @table_variable exec [dbo].[Maininsert] @Title
select MAX(id) as Ne_Identity from @table_variable
select *
from dbo.Main
27 янв 16, 13:08    [18735383]     Ответить | Цитировать Сообщить модератору
 Re: Как написать инициализационный скрипт t-sql ?  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4804
ProBiotek,

воспользуйтесь OUTPUT

https://msdn.microsoft.com/en-us/library/ms177564.aspx
27 янв 16, 13:11    [18735399]     Ответить | Цитировать Сообщить модератору
 Re: Как написать инициализационный скрипт t-sql ?  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
ой. рано отправил.

DaniilSeryi, Спасибо, работает !!

alexeyvg,

Вы говорите, что решение от DaniilSeryi обладает недостатками (INSERT таблица, EXEC процедура)?
Надеюсь не критичными. Я его буду применять - работает ведь, то что мне нужно. Надеюсь не напорюсь на сюрприз какой-то.
27 янв 16, 13:11    [18735403]     Ответить | Цитировать Сообщить модератору
 Re: Как написать инициализационный скрипт t-sql ?  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
a_voronin,

Конечно, Output пожалуй это наиболее правильный вариант - для уже новых процедур.
Просто процедуру не хочется переписывать, чтобы не сломать где-то чего-то - ведь нужно будет везде поправить вызов процедуры на новый (в процедуре станет два параметра а не один).
27 янв 16, 13:13    [18735419]     Ответить | Цитировать Сообщить модератору
 Re: Как написать инициализационный скрипт t-sql ?  [new]
Glory
Member

Откуда:
Сообщений: 104760
ProBiotek
Просто процедуру не хочется переписывать, чтобы не сломать где-то чего-то - ведь нужно будет везде поправить

если у вас уже все работает, то что вы вообще лезите в эту процедуру ?
27 янв 16, 13:46    [18735623]     Ответить | Цитировать Сообщить модератору
 Re: Как написать инициализационный скрипт t-sql ?  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
Glory,

Я и не лезу в это процедуру.

Простая связь Master-Child. Сейчас она создается на уровне программы.
Понадобилось и на t-sql создавать эту пару. Master и Child к нему, само собой используя существующий функционал а не плодя дублирование кода. Вот и напоролся.
27 янв 16, 14:16    [18735772]     Ответить | Цитировать Сообщить модератору
 Re: Как написать инициализационный скрипт t-sql ?  [new]
Glory
Member

Откуда:
Сообщений: 104760
ProBiotek
Понадобилось и на t-sql создавать эту пару. Master и Child к нему, само собой используя существующий функционал а не плодя дублирование кода. Вот и напоролся.

Если вам понадобилось перенести логику на сторону сервера, то почему вас удивляет, что код нужно переписать ?
27 янв 16, 14:18    [18735784]     Ответить | Цитировать Сообщить модератору
 Re: Как написать инициализационный скрипт t-sql ?  [new]
komrad
Member

Откуда:
Сообщений: 5252
ProBiotek
Понадобилось и на t-sql создавать эту пару. Master и Child к нему, само собой используя существующий функционал а не плодя дублирование кода. Вот и напоролся.

ну, теоретически, можно и триггер написать
27 янв 16, 14:45    [18735940]     Ответить | Цитировать Сообщить модератору
 Re: Как написать инициализационный скрипт t-sql ?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31438
ProBiotek
Вы говорите, что решение от DaniilSeryi обладает недостатками (INSERT таблица, EXEC процедура)?
Надеюсь не критичными. Я его буду применять - работает ведь, то что мне нужно. Надеюсь не напорюсь на сюрприз какой-то.
Например, нельзя использовать вложенные процедуры с INSERT ... EXEC
Или нельзя работать с несколькими рекордсетами.
Ещё процедуры будут постоянно перекомпилироваться, при каждом вызове.

Для возврата скалярного значения это использовать неразумно.
27 янв 16, 18:47    [18737243]     Ответить | Цитировать Сообщить модератору
 Re: Как написать инициализационный скрипт t-sql ?  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31438
ProBiotek
Понадобилось и на t-sql создавать эту пару. Master и Child к нему, само собой используя существующий функционал а не плодя дублирование кода.
Нельзя разрабатывать для MS SQL, не делая паст-копи и повторно используя код. Это концептуально неправильно, получится убогая поделка.

Я же говорю, эти меры специально сделаны, что бы было трудно писать нормальный структурированный код. Вам придётся с этим смириться, либо использовать другой продукт.
27 янв 16, 18:49    [18737250]     Ответить | Цитировать Сообщить модератору
 Re: Как написать инициализационный скрипт t-sql ?  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
ProBiotek
Я искал способ без Output просто. Наверное стоило это упомянуть.
Просто я не могу изменить существующую процедуру...
ProBiotek
Конечно, Output пожалуй это наиболее правильный вариант - для уже новых процедур.
Просто процедуру не хочется переписывать, чтобы не сломать где-то чего-то - ведь нужно будет везде поправить вызов процедуры на новый (в процедуре станет два параметра а не один).
Так вы совсем не можете ее изменять или просто не хотите менять набор параметров чтобы ничего нигде не упало? Если второе, ну так сделайте новый output параметр необязательным (с дефолтным значением) и все старые вызовы как работали так и будут работать.

Create procedure [dbo].[MainInsert]
		 @Title nvarchar(max),
		 @output int = NULL output 
as
27 янв 16, 20:39    [18737663]     Ответить | Цитировать Сообщить модератору
 Re: Как написать инициализационный скрипт t-sql ?  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
Mind,

Спасибо.
Просто боюсь неизвестности :)
3 фев 16, 21:15    [18770054]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить