Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Контекст исполнения Exec() и доступ из него ко внешним переменным
|
|||
|---|---|---|---|
|
#18+
Пусть есть ХП. В ней определены какие-то переменные. Далее в ней выполняем через EXEC() некий SQL-запрос. Вопрос: почему при этом если в текст этого запроса включить переменные, определённые в ХП, то возникает ошибка "переменная не определена"? В то же время, если внутри ХП вписать текст запроса с использованием этой же переменной - то всё отлично рабтает? Видимо запрос из EXEC() выполняется "в другом контексте", где не видны локальные переменные. но где это описано в справке? не могу найти. И есть ли способ значения "внешних" по отношению к тексту запроса внутри EXEC() использовать в этом запросе? Пример о чем речь: DECLARE @id int SET @id = 5 SELECT * FROM table WHERE id = @id -- так работает EXEC('SELECT * FROM table WHERE id = @id') -- а так не работает, "неизвестная переменная @id", почему? Если ли способ внутри запроса EXEC() увидеть @id ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.01.2019, 13:53 |
|
||
|
Контекст исполнения Exec() и доступ из него ко внешним переменным
|
|||
|---|---|---|---|
|
#18+
Sergey Kasatkin почему при этом если в текст этого запроса включить переменные, определённые в ХП, то возникает ошибка "переменная не определена"?Потому что у переменных есть документированная область видимости. Sergey KasatkinЕсли ли способ внутри запроса EXEC() увидеть @id ? Код: sql 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.01.2019, 13:59 |
|
||
|
Контекст исполнения Exec() и доступ из него ко внешним переменным
|
|||
|---|---|---|---|
|
#18+
Sergey Kasatkin, Для этого используют sp_ExecuteSql ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.01.2019, 14:00 |
|
||
|
Контекст исполнения Exec() и доступ из него ко внешним переменным
|
|||
|---|---|---|---|
|
#18+
zbySergey Kasatkin, Для этого используют sp_ExecuteSqlМожно сформировать строку запроса @sql с использованием переменных и выполнить запрос EXEC(@sql) без всякой процедуры. А вот вернуть наверх значение - это да, только через OUTPUT-параметры sp_executesql ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.01.2019, 14:12 |
|
||
|
Контекст исполнения Exec() и доступ из него ко внешним переменным
|
|||
|---|---|---|---|
|
#18+
Спасибо всем ответившим, теперь понял. Попутно вопрос, если можно. Верно ли я знаю/помню, что использование запроса в виде Код: sql 1. более эффективно (понятно, что для разных случаев мы передаём разные значения @id), нежели выполнение запроса Код: sql 1. когда на место 5 мы подставляем (динамическим формированием текста SQL-запроса) разные значения? Например, эффективнее тем, что при построении плана запроса в первом случае учитывается, что вот тут будет изменяемое значение, что ускорит использование этого плана запроса для последующих запросов? У меня есть какое-то воспоминание, что способ с явным указанием переменных рекомендовался как более эффективный. Но либо память подводит, либо уже всё давно не так. Хотелось бы уточнить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.01.2019, 14:50 |
|
||
|
Контекст исполнения Exec() и доступ из него ко внешним переменным
|
|||
|---|---|---|---|
|
#18+
Sergey Kasatkin, Емнип не более эффективно, но создается прецедент прослушивания параметров (в зависимости от настроек параметризации для базы), в результате которого план запроса может быть использован повторно. При указании скаляров будет закеширован новый план для каждого значения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.01.2019, 16:40 |
|
||
|
Контекст исполнения Exec() и доступ из него ко внешним переменным
|
|||
|---|---|---|---|
|
#18+
Владислав КолосовЕмнип не более эффективно, но создается прецедент прослушивания параметров вообще-то у него не параметры, а переменные. ибо даже если внутри процедуры написано Код: sql 1. 2. 3. 4. то это все равно переменная, а не параметр. переменные не прослушиваются. поэтому как раз в случае переменных не используется статистика. зато если влепить константу, то как раз используется, так что план, скорее всего, будет оптимальным. будет ли ТС использовать sp_executesql, еще вопрос. но если будет, то вот тогда да, сработает прослушивание. правда, всего лишь в первое выполнение ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.01.2019, 17:12 |
|
||
|
Контекст исполнения Exec() и доступ из него ко внешним переменным
|
|||
|---|---|---|---|
|
#18+
Yasha123поэтому как раз в случае переменных не используется статистика. зато если влепить константу, то как раз используется, так что план, скорее всего, будет оптимальным. статистика все таки используется, только не в полном объеме. (если мы говорим про запрос в принципе, а не конкретный текст select * from вверху) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.01.2019, 18:27 |
|
||
|
Контекст исполнения Exec() и доступ из него ко внешним переменным
|
|||
|---|---|---|---|
|
#18+
DzianisYasha123поэтому как раз в случае переменных не используется статистика. зато если влепить константу, то как раз используется, так что план, скорее всего, будет оптимальным. статистика все таки используется, только не в полном объеме. (если мы говорим про запрос в принципе, а не конкретный текст select * from вверху) это типа как? 1/3 статистики или 1/10? --- в случае переменной при отсутствии option(recompile) используется стандартная оценка в % от числа строк таблицы. никакая колоночная статистика не используется ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.01.2019, 18:37 |
|
||
|
Контекст исполнения Exec() и доступ из него ко внешним переменным
|
|||
|---|---|---|---|
|
#18+
Yasha123, я же правильно понимаю, что при указании переменной без rebuild выполняется оптимизация for unknown? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.01.2019, 18:37 |
|
||
|
Контекст исполнения Exec() и доступ из него ко внешним переменным
|
|||
|---|---|---|---|
|
#18+
recompile, конечно же. Ребилдил таблицы, прицепилось ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.01.2019, 18:39 |
|
||
|
Контекст исполнения Exec() и доступ из него ко внешним переменным
|
|||
|---|---|---|---|
|
#18+
Yasha123в случае переменной при отсутствии option(recompile) используется стандартная оценка в % от числа строк таблицы. никакая колоночная статистика не используется оценка в % от числа строк таблицы - это то же статистика то ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2019, 18:13 |
|
||
|
Контекст исполнения Exec() и доступ из него ко внешним переменным
|
|||
|---|---|---|---|
|
#18+
Dzianis, да надо же. оценка "верну одну треть таблицы вне зависимости от числа строк" статистикой и близко не пахнет. это эмпирическая оценка ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2019, 19:00 |
|
||
|
Контекст исполнения Exec() и доступ из него ко внешним переменным
|
|||
|---|---|---|---|
|
#18+
Yasha123Dzianis, да надо же. оценка "верну одну треть таблицы вне зависимости от числа строк" статистикой и близко не пахнет. это эмпирическая оценкаКонечно значение переменной не известно и поэтому гистограмма статистики не используется, но зато используется DENSITY_VECTOR, и не надо говорить что это не часть статистики. Если сделать условие на равенство для достаточно равномерно распределенных значений, то количество ожидаемых строк будет достаточно точным. В случае же если значения неравномерно распределены, то прослушивание паматров и использование реальных значений статистики будет работать хорошо только до тех пор пока случайно не скомпилируется план с "нестандартным" значением и тогда это может оказаться еще хуже, чем использование оценки по DENSITY. Варианты решения в такой ситуации либо OPTION(RECOMPILE), что будет работать в любом случае, хоть переменная, хоть параметр, либо OPTIMIZE(FOR UNKNOWN) что абсолютно тоже самое что и переменная. Так что оценка по DENSITY конечно не идеальная, но не так уж плоха. Использование константы несомненно лучше, но 100 тысяч одинаковых запросов с разными значениями сожрут кучу памяти и процессорного времени на перекомпиляцию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.02.2019, 05:04 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=39764355&tid=1688345]: |
0ms |
get settings: |
8ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
26ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
45ms |
get tp. blocked users: |
1ms |
| others: | 226ms |
| total: | 339ms |

| 0 / 0 |
