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

Откуда: оттуда
Сообщений: 360
Простейший запрос
if (1=0)
begin
declare @foo int = 1;
end
select @foo;

В результате дает на выходе NULL. То есть переменная объявилась, хотя условие не соблюдено. Я правильно понимаю, что скуль при анализе объявляет все переменные, а потом уже смотрит на условия IF и, следуя условию, присваивает значение и именно по этому я имею видимость переменной. Может быть есть некий порядок при разборе блока. Что то типа "сначала объявляем и сохраняем в памяти все переменные, далее IF, далее еще что нибудь...."?
26 ноя 19, 18:52    [22026000]     Ответить | Цитировать Сообщить модератору
 Re: Порядок выполнения команд и объявление переменной  [new]
msLex
Member

Откуда:
Сообщений: 7730
Ёжик25,

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

if (1=0)
	declare @foo int = 1;
else 
	declare @foo int = 2;

select @foo;
26 ноя 19, 18:59    [22026005]     Ответить | Цитировать Сообщить модератору
 Re: Порядок выполнения команд и объявление переменной  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6794
msLex
Ёжик25,

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

if (1=0)
	declare @foo int = 1;
else 
	declare @foo int = 2;

select @foo;

ну тогда можно было бы

автор
SET @foo = 2
declare @foo int = 1;

точно не знаю, но имхо внутри IF определение срабатывает из-за того что компилятор уловия всё равно комилирует и в результате выносить declare в начало
26 ноя 19, 19:03    [22026009]     Ответить | Цитировать Сообщить модератору
 Re: Порядок выполнения команд и объявление переменной  [new]
Ёжик25
Member

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

Вот оно что. Благодарю. На самом деле я с этим столкнулся, объявляя табличную переменную в теле курсора. Почему то мне всегда казалось, что каждая "итерация" курсора - это отдельный батч. Вышло, что табличная переменная копила данные при каждом прохождении по курсору. И игнорируется каждый раз ее объявление. Во всяком случае не выдает ошибку. Вот именно это меня смутило.
Тогда выходит, что скуль собирает при разборе информацию об объявлениях переменных, а потом игнорирует все declare, если они для переменных с таким же именем опять встречаются по ходу логики выполнения
26 ноя 19, 19:09    [22026015]     Ответить | Цитировать Сообщить модератору
 Re: Порядок выполнения команд и объявление переменной  [new]
Ёжик25
Member

Откуда: оттуда
Сообщений: 360
[quot TaPaK#22026009]
msLex
Ёжик25,

точно не знаю, но имхо внутри IF определение срабатывает из-за того что компилятор уловия всё равно комилирует и в результате выносить declare в начало


Если он компилируется условия "все равно", то значит тратит на это ресурсы. И по логике выходит, что я могу миллион конструкций с IF накрутить, при этом ничего выполняться не будет, но ресурсы потратятся? Типа IF 1=0, else if 2=0 и так далее...
26 ноя 19, 19:12    [22026020]     Ответить | Цитировать Сообщить модератору
 Re: Порядок выполнения команд и объявление переменной  [new]
msLex
Member

Откуда:
Сообщений: 7730
Ёжик25
Если он компилируется условия "все равно", то значит тратит на это ресурсы. И по логике выходит, что я могу миллион конструкций с IF накрутить, при этом ничего выполняться не будет, но ресурсы потратятся? Типа IF 1=0, else if 2=0 и так далее...


Да


вот так, вы тоже получите ошибку

if  1=2 
create table #t(id int)
else 
create table #t(id int)

TaPaK
msLex
Ёжик25,

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

if (1=0)
	declare @foo int = 1;
else 
	declare @foo int = 2;

select @foo;


ну тогда можно было бы

автор
SET @foo = 2
declare @foo int = 1;

точно не знаю, но имхо внутри IF определение срабатывает из-за того что компилятор уловия всё равно комилирует и в результате выносить declare в начало


тут, похоже, все сложнее

вот это работает

if (1=0)
	declare @foo int = 1;
else 
	select @foo;


а вот это нет

if (1=0)
	select @foo;
else 
	declare @foo int = 1;
26 ноя 19, 19:20    [22026026]     Ответить | Цитировать Сообщить модератору
 Re: Порядок выполнения команд и объявление переменной  [new]
invm
Member

Откуда: Москва
Сообщений: 9122
msLex
тут, похоже, все сложнее
Или наоборот, проще: тупо что раньше встретится, - объявление или использование, - без учета control flow
26 ноя 19, 19:59    [22026062]     Ответить | Цитировать Сообщить модератору
 Re: Порядок выполнения команд и объявление переменной  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7399
Ёжик25,

переменные инициализируются при первом проходе один раз, в рантайме все инициализации игнорируются. Например, Вы можете объявить переменную в блоке кода, в который выполнение никогда не попадает, тем не менее, код будет работать.
27 ноя 19, 11:09    [22026414]     Ответить | Цитировать Сообщить модератору
 Re: Порядок выполнения команд и объявление переменной  [new]
Ёжик25
Member

Откуда: оттуда
Сообщений: 360
Владислав Колосов,
благодарю. Вопрос закрыт.
27 ноя 19, 14:23    [22026707]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить