powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Изменение обьекта через sp_executesql с параметрами
14 сообщений из 14, страница 1 из 1
Изменение обьекта через sp_executesql с параметрами
    #40072940
otets1988
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброй ночи,

Обращаюсь к коллективному разуму за подсказкой по одному вопросу, который мне никак не дает покоя.
Я хочу изменить представление/функцию/процедуру через динамический запрос с использованием sp_executesql с параметрами.
Как написать мой пример без параметров я знаю. Также вопрос не стоит в том зачем мне это надо.
Хочу лишь попытаться разобраться в чем проблема изменения/создания обьекта с использованием sp_executesql с параметрами.

Пример
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
if object_id('dbo.TestView', 'v') is not null drop view dbo.TestView;
go
create view dbo.TestView as select 1 as col1;
go
select * from dbo.TestView

declare @cmd nvarchar(4000);
declare @obj_id int;
select @obj_id = min(object_id) from sys.objects;
set @cmd = N'alter view [dbo].[TestView] as select * from sys.objects where object_id = @obj_id;';
print @cmd
exec dbo.sp_executesql @cmd, N'@obj_id int', @obj_id;



Получаю ошибку
Код: plaintext
1.
Msg 156, Level 15, State 1, Line 5
Incorrect syntax near the keyword 'view'.

Если убрать параметры в sp_executesql, а переменную @obj_id сцепить через +, то все работает, как через EXEC(@cmd), так и через exec dbo.sp_executesql @cmd. Важно именно с параметром.

Из единственных логических обьяснений по этому поводу я вычитал, что sp_executesql с параметрами неявно добавляет перед DDL своё обьявление и в результате alter становится не первым в батче. Но подобного обьяснения поведения я не нашел на уровне документации. Может кому-то попадался такой случай и знает в чем причина подобного ограничения?

P.S. Прошу не цепляться за представление и писать, что мне надо UDF вместо view. Аналогичная проблема и с функциями и с процедурами.

Спасибо!
...
Рейтинг: 0 / 0
Изменение обьекта через sp_executesql с параметрами
    #40072952
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не придумывайте сложностей там, где их нет.

Код: sql
1.
2.
set @cmd = N'alter view [dbo].[TestView] as select * from sys.objects where object_id = ' + cast ( @obj_id as nvarchar (50) ) + ';'
exec dbo.sp_executesql @cmd
...
Рейтинг: 0 / 0
Изменение обьекта через sp_executesql с параметрами
    #40072966
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
otets1988
Важно именно с параметром.

Нема такого синтаксиса декларации View.
Не бывает там параметров.

То, что ты пишешь эквивалентно
Код: sql
1.
2.
declare @obj_id int = 123;
alter view [dbo].[TestView] as select * from sys.objects where object_id = @obj_id;


так низзя.
...
Рейтинг: 0 / 0
Изменение обьекта через sp_executesql с параметрами
    #40072982
otets1988
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Гавриленко Сергей Алексеевич
Не придумывайте сложностей там, где их нет.

Код: sql
1.
2.
set @cmd = N'alter view [dbo].[TestView] as select * from sys.objects where object_id = ' + cast ( @obj_id as nvarchar (50) ) + ';'
exec dbo.sp_executesql @cmd


Не спора ради, а действительно хочу разобраться и понять почему вы считаете, что я придумываю сложности?
Моя логика с использованием параметризированного динамического SQL основывается на рекомендациях использовать sp_executesql, как более безопасную альтернативу обычному exec.

К примеру, вот что пишет Ицик:
авторСуществует множество методов предупреждения внедрения SQL-кода, и это тоже обширная тема. С точки зрения разработчика T-SQL, одним из наиболее предпочтительных способов является параметризация генерации и исполнения динамического SQL с использованием хранимой процедуры sp_executesql.

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


Да и в других местах я встречал полно подобных рекомендаций. Но так как мой любимый автор Ицик, то и решил на него сослаться.
Вполне возможно, что я действительно перегибаю и хочу использовать параметризированный динамический sql, там где он не может быть выполнен. И похоже, что я нашел пример такого поведения.

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


P.S. Я в своем коде уже сделал реализацию подобную вашей, но через replace нужных параметров внутри строки.
...
Рейтинг: 0 / 0
Изменение обьекта через sp_executesql с параметрами
    #40072984
otets1988
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
aleks222
otets1988
Важно именно с параметром.

Нема такого синтаксиса декларации View.
Не бывает там параметров.

То, что ты пишешь эквивалентно
Код: sql
1.
2.
declare @obj_id int = 123;
alter view [dbo].[TestView] as select * from sys.objects where object_id = @obj_id;


так низзя.


Значит все-таки я уже ранее нашел ответ на мой же вопрос?
otets1988

Из единственных логических обьяснений по этому поводу я вычитал, что sp_executesql с параметрами неявно добавляет перед DDL своё обьявление и в результате alter становится не первым в батче. Но подобного обьяснения поведения я не нашел на уровне документации. Может кому-то попадался такой случай и знает в чем причина подобного ограничения?


Просто я себе представлял сборку этого динамического кода по другому...
Если же выполнять обычный селект через параметризированный динамический запрос, а затем принтануть текст, то вместо параметров в тексте мы увидим значения, которые были подставлены через параметры. То есть моё представление о последовательности было следующим:
1. Создание строки с параметрами внутри
2. Передача параметров в динамический код через sp_executesql
3. Исполнение кода (в коде уже нет параметров, а только значения) через sp_executesql

Видимо пункт 2 и 3 выполняются одновременно и для его реализации идет элементарное декларирование параметров перед запросом. Выходит так? Меня сбил с толку результат принта? И ограничение для sp_executesql с параметрами являются все DDL операции?
...
Рейтинг: 0 / 0
Изменение обьекта через sp_executesql с параметрами
    #40072990
otets1988
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
otets1988
Если не сложно, то был бы благодарен за тезисное пояснение этого момента, почему вы считаете, что я усложняю.

Как по мне, то с параметрами как раз гораздо проще, так как меньше вот этих канкатенаций писать с преобразованием, которые только усложняют чтение кода, когда переменных становиться много
...
Рейтинг: 0 / 0
Изменение обьекта через sp_executesql с параметрами
    #40073082
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
otets1988,

выполнение DDL на сервере - вообще плохая идея, как показывает практика. Такой код становится неуправляемым и сложным в сопровождении. Лучше использовать скрипты и SQLCMD для публикации обновлений с подстановочными переменными.

В Вашем случае необходимо использовать табличную функцию, поскольку Вы хотите получить параметризированное представление.
Например:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
CREATE FUNCTION dbo.GetData (@obj_id INT)
RETURNS TABLE
AS
RETURN (select * from sys.objects where object_id = @obj_id);
GO


SELECT * FROM dbo.GetData(100);
...
Рейтинг: 0 / 0
Изменение обьекта через sp_executesql с параметрами
    #40073136
otets1988
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владислав Колосов
otets1988,
выполнение DDL на сервере - вообще плохая идея, как показывает практика. Такой код становится неуправляемым и сложным в сопровождении. Лучше использовать скрипты и SQLCMD для публикации обновлений с подстановочными переменными.

Спасибо за совет. Приму к сведению и постараюсь избегать подобной практики в работе.

Владислав Колосов
otets1988,
В Вашем случае необходимо использовать табличную функцию, поскольку Вы хотите получить параметризированное представление.
Например:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
CREATE FUNCTION dbo.GetData (@obj_id INT)
RETURNS TABLE
AS
RETURN (select * from sys.objects where object_id = @obj_id);
GO


SELECT * FROM dbo.GetData(100);


В моем случае, вся суть сводится к изменению обьекта через параметризованный динамический запрос.
И если в исходном примере заменить view на вашу параметризованную функцию, то ничего не изменится.
Ошибка будет прежней, только слово view поменяется на function
Код: sql
1.
2.
Msg 156, Level 15, State 1, Line 9
Incorrect syntax near the keyword 'FUNCTION'.
...
Рейтинг: 0 / 0
Изменение обьекта через sp_executesql с параметрами
    #40073241
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
otets1988,

при использовании функции не потребуется пересоздавать представление для каждого нового ObectID, следовательно, не потребуется выполнять динамический запрос.
...
Рейтинг: 0 / 0
Изменение обьекта через sp_executesql с параметрами
    #40073268
otets1988
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владислав Колосов
otets1988,

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

Теперь понял о чем вы. Мой пример был абстрактным и оказывается, что не до конца полным с точки зрения его похожести на боевой. В "боевом" динамическом примере у меня еще и поля неизвестные идут, которые я должен собирать. Поэтому функция не сможет это решить.

Хотя ваш пример дал осознать тот факт, что мне все ровно ведь не обойтись без конкатенации полей в моем динамическом коде.
Даже, если бы и была возможность через параметры sp_executesql толкать сами параметры, мне все ровно пришлось бы конкатенировать поля. В результате бы вышла каша из разных подходов - конкатенация и параметры.
...
Рейтинг: 0 / 0
Изменение обьекта через sp_executesql с параметрами
    #40073292
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
otets1988,

в таком случае, пример не репрезентативный и не показывает того, чего вы добиваетесь в итоге, он отображает лишь выбранное Вами решение и не более того. Вполне возможно, что существует другое решение задачи.
...
Рейтинг: 0 / 0
Изменение обьекта через sp_executesql с параметрами
    #40073327
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав Колосов
в таком случае, пример не репрезентативный и не показывает того, чего вы добиваетесь в итоге
Лучше было бы привести пример с созданием базы данных, это лучше покажет, что нужно ТС, и для чего.
Создать БД, имя которой задаётся параметром.
...
Рейтинг: 0 / 0
Изменение обьекта через sp_executesql с параметрами
    #40073739
otets1988
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И все же главная задача стояло в том, чтобы понять работает ли создание/модификация обьектов через параметризированный динамический запрос и если нет, то почему. Я получил здесь ответ, что не работает, так как перед созданием/модификацией обьекта через динамический запрос с параметром неявно (по крайней мере для меня это было так, свою логику размышлений я выше описал) происходит обьявление переменной, что не дает быть первой операцией DDL в батче.

За остальные советы, рекомендации и замечания я отдельно благодарен всем отписавшимся!
...
Рейтинг: 0 / 0
Изменение обьекта через sp_executesql с параметрами
    #40073742
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
otets1988
Я получил здесь ответ, что не работает, так как перед созданием/модификацией обьекта через динамический запрос с параметром неявно (по крайней мере для меня это было так, свою логику размышлений я выше описал) происходит обьявление переменной, что не дает быть первой операцией DDL в батче.

За остальные советы, рекомендации и замечания я отдельно благодарен всем отписавшимся!


Проблема не в первой операции в батче, а в том, что вы пытались внутри view использовать переменную объявленные вне ее.
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Изменение обьекта через sp_executesql с параметрами
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]