Разлики между операторите SET и SELECT при присвояване на стойности на променливи, Олонцев Сергей
Блог за наука за данни
Разлики между операторите SET и SELECT при присвояване на стойности на променливи
В SQL Server езикът T-SQL има два оператора, SET и SELECT, като и двата могат да се използват за присвояване на стойности на променливи. В някои ситуации използването на един или друг оператор може да доведе до неочаквани и непредвидими резултати. В тази статия бих искал да разгледам по-отблизо разликите между тях и да говоря за различните капани, в които можете да попаднете.
На първо място, и двата оператора могат да се използват еднакво за присвояване на фиксирани стойности на променливи. Въпреки това операторът SET е стандарт за езика SQL, докато операторът SELECT е само характеристика на диалекта T-SQL в SQL Server.
декларирайте @int_example int, @dt_example datetime, @str_example varchar(255); set @int_example = 1; set @dt_example = getdate(); set @str_example = 'qwe'; изберете @int_example, @dt_example, @str_example; изберете @int_example = 1; изберете @dt_example = getdate(); изберете @str_example = 'qwe'; изберете @int_example, @dt_example, @str_example; отивам
Ако обаче искаме да инициализираме няколко променливи наведнъж в една операция, тогава трябва да използваме оператора SELECT.
декларирайте @int_example int, @dt_example datetime, @str_example varchar(255); изберете @int_example = 1, @dt_example = getdate(), @str_example = 'qwe'; изберете @int_example, @dt_example, @str_example; отивам
Ако се опитаме да използваме SET в тази ситуация, ще получим грешка, защото той просто не поддържа такава операция.
декларирайте @int_example int, @dt_example datetime, @str_example varchar(255); set @int_example = 1, @dt_example = getdate(), @str_example = 'qwe'; изберете @int_example,@dt_example, @str_example; отивам
Съобщение 102, ниво 15, състояние 1, ред 7Неправилен синтаксис близо до „,“.
И двата оператора могат да се използват и за присвояване на стойности на променливи от таблица. Въпреки това, ако SELECT може да се използва директно, тогава в случая на SET, все още трябва да използвате SELECT, за да получите селекция от таблицата, и вече да опитате да присвоите нейните резултати на променлива.
създаване на таблица #tmp ( >
Единственото нещо, което трябва да имате предвид е, че ако резултатът от заявка към таблицата върне повече от една стойност, тогава в случай на операцията SET ще получим грешка.
създаване на таблица #tmp ( >
Съобщение 512, ниво 16, състояние 1, ред 25Подзаявката върна повече от 1 стойност. Това не е разрешено, когато подзаявката следва =, !=, , >= или когато подзаявката се използва като израз.
В случай на използване на израза SELECT няма да има грешка, но в общия случай не можем точно да предвидим коя от стойностите, които отговарят на условието за избор, ще бъде присвоена на променливата. Разгледайте първия случай, в който заявката ще върне 32.
създаване на таблица #tmp ( >
В следния случай заявката връща 31.
създаване на таблица #tmp ( >
Както видяхме, недетерминизмът на извадката може да доведе до неочаквани резултати. Ето защо в този случай бих препоръчал да използвате оператора SET, за да получите поне грешка и също така да наблюдавате условията за избор, за да избегнете подобни ситуации. И още нещо, на което бих искал да се спра, когато нито един запис не попада в условията за избор и стойността на променливата вече е инициализирана с някаква стойност.
създаване на таблица #tmp ( >
Както можем лесно да видим, операторът SET присвои стойност на променливата NULL итук операторът SELECT просто игнорира присвояването и оставя стойността на променливата такава, каквато беше от този опит. В резултат на това, ако използваме оператора SELECT, не можем да знаем със сигурност дали стойността на променливата е инициализирана или не. Като алтернатива можем да проверим стойността на променливата @@rowcount, която ще бъде нула, ако операторът SELECT не намери никакви записи, съответстващи на условието, и инициализацията не се случи.
създаване на таблица #tmp ( >
За да обобщим, можете да използвате и двата оператора, но трябва ясно да разберете в коя ситуация и какво да очаквате от тях. Използвайте оператора SET, ако:
- Ако присвоявате фиксирани стойности на променливи, без да използвате заявки и искате да следвате стандартите.
- Очаквайте променливата да бъде зададена на NULL, ако заявката не върне резултати.
- Една заявка може да върне множество стойности и вие искате да следите тези ситуации.
И използвайте оператора SELECT, ако:
- Искате да присвоите стойности на няколко променливи наведнъж в една инструкция.
- В случай на извличане на стойности от таблицата, ние сме готови да контролираме дали инициализацията действително е извършена, например, използвайки @@rowcount.