Я знаком с MsSQL, и поэтому мне никогда не приходило в голову задавать такой вопрос. Ответы, представленные здесь, объяснили мне то, о чем я не знал ИДЕИ !! Thx ..
Разница между переменной процедуры и пользовательской переменной, специфичной для сеанса, заключается в том, что переменная процедуры инициализируется повторно при NULLкаждом вызове процедуры, в то время как переменная, специфичная для сеанса, не имеет значения:
Как видите, var2(переменная процедуры) переинициализируется при каждом вызове процедуры, в то время как@var2 ( сеансу) - нет.
(В дополнение к пользовательским переменным, MySQL также имеет некоторые предопределенные «системные переменные», которые могут быть «глобальными переменными», такими как @@global.portили «переменные сеанса», такие как @@session.sql_mode; эти «переменные сеанса» не связаны с пользовательским определением сеанса. переменные.)
Также обратите внимание, что есть глобальные переменные: см. SELECT @@version;Например. Это также причина, почему использование DELIMITER @@не очень хорошая идея.
Mchl
13
это создает новые вопросы для новичков ... есть ли разница между "var = var" и "var: = var", как в вашем примере?
Confiq
13
@confiq: нет ни одного.
Quassnoi
10
Еще один вопрос для новичка. Когда рекомендуется использовать @против нет?
pixelfreak
73
@confiq, @Quassnoi: между :=и есть одно существенное различие, заключающееся в =том, что он :=везде работает как оператор присваивания переменной, а =работает только в SETвыражениях и везде является оператором сравнения. Таким образом SELECT @var = 1 + 1;, @var останется неизменным и вернет логическое значение (1 или 0 в зависимости от текущего значения @var), а SELECT @var := 1 + 1;изменит @var на 2 и вернет 2.
Вне хранимых программ, a variable, без @, является системной переменной , которую вы не можете определить самостоятельно.
Область действия этой переменной - весь сеанс. Это означает, что, хотя ваше соединение с базой данных существует, переменная все еще может использоваться.
Это отличается от MSSQL, где переменная будет доступна только в текущем пакете запросов (хранимая процедура, сценарий или другое). Он не будет доступен в другой партии в том же сеансе.
@RobM, они называются системными переменными, а не переменными сеанса.
Pacerier
1
@Pacerier: я неправильно читаю документы? "" "Чтобы явно указать, что переменная является переменной сеанса, перед ее именем укажите SESSION, @@ session. Или @@." ""
RobM
5
@RobM, ты неправильно это читаешь. Прочитайте весь абзац, а не только абзац внутри маркированного списка. Проще говоря, существует два вида переменных сеанса: 1) определяемые пользователем переменные сеанса и 2) определяемые системой переменные сеанса. Вы не можете установить пользовательскую переменную сеанса с помощью @@. Так , например, set@@my_var=1, set@@session.my_var=1и set session my_var=1не будет работать , потому что my_varэто не система переменной, в то время как мы можем сделать set@@big_tables=1, set@@session.big_tables=1и set session big_tables=1потому , что big_tablesэто системная переменная.
Pacerier
1
@GovindRai: В ответе Quassnoi var2это переменная без @префикса, но это не системная переменная: это переменная процедуры. Это разрешено, потому что он находится в хранимой процедуре (она же хранимая программа) Вне хранимых процедур переменная без @является системной переменной.
LarsH
10
MSSQL требует, чтобы переменные внутри процедур были DECLAREd, и люди используют синтаксис @Variable (DECLARE @TEXT VARCHAR (25) = 'text'). Кроме того, MS допускает объявления в любом блоке процедуры, в отличие от mySQL, который требует всех DECLARE вверху.
Хотя это хорошо для командной строки, я чувствую, что использование «set = @variable» в хранимых процедурах в MySQL рискованно. Там нет области видимости и переменные живут за пределами границ области видимости. Это похоже на объявление переменных в JavaScript без префикса «var», которые затем являются глобальным пространством имен и создают неожиданные коллизии и перезаписи.
Я надеюсь, что хорошие люди в mySQL разрешат DECLARE @Variable на различных уровнях блоков в хранимой процедуре. Обратите внимание на @ (на знак). Префикс @ sign помогает отделить имена переменных от имен столбцов таблицы, поскольку они часто совпадают. Конечно, всегда можно добавить префикс «v» или «l_», но знак @ - это удобный и лаконичный способ, чтобы имя переменной совпадало со столбцом, из которого вы, возможно, извлекаете данные, не забивая их.
MySQL является новым для хранимых процедур, и они сделали хорошую работу для своей первой версии. Будет приятно посмотреть, где они принимают форму, и посмотреть, как развиваются аспекты серверной части языка.
В принципе, я использую UserDefinedVariables (с префиксом @) в хранимых процедурах. Это облегчает жизнь, особенно когда мне нужны эти переменные в двух или более хранимых процедурах. Просто когда мне нужна переменная только в ОДНОЙ хранимой процедуре, тогда я использую системную переменную (без префикса @).
@Xybo: я не понимаю, почему использование @variables в StoredProcedures должно быть рискованным. Не могли бы вы объяснить, немного «проще» и «границы» (для меня, как новичка)?
Это нарушает основные принципы разработки программного обеспечения. Пожалуйста, не пишите другую строку кода, пока вы точно не знаете, что такое область действия, и почему использование глобальных переменных - вообще ужасная идея. Когда я взял 101 класс программирования, насколько я помню, использование global для почти чего-либо привело бы к автоматическому «F». Есть особые исключения, но, как правило, просто не делайте этого!
BuvinJ
Почему? - @Variables абсолютно обычны в каждой книге MySQL.
Питер
Конечно, в «плоском» сценарии без вызовов функций, процедур, триггеров и т. Д., И если вы просто собираетесь выполнить этот простой сценарий или ограниченный набор команд, а затем завершить сеанс (тем самым уничтожив глобальные переменные). В таком случае, продолжайте и используйте их, если хотите. Но НЕ используйте их внутри функции! Если вы просто используете глобальные переменные или область действия Google, вы мгновенно найдете широкую поддержку идеи, что они повсеместно осуждаются. Вот отправная точка: wiki.c2.com/?GlobalVariablesAreBad или для более общего объяснения: en.wikipedia.org/wiki/Global_variable
BuvinJ
2
В MySQL @variables являются глобальными. Это легко подтверждается. Установите один за пределами функции, а затем оцените его внутри одного. И наоборот, установите один внутри функции и оцените его за ее пределами. Вы увидите, что функция не защищает область таких. Они наступают друг другу на пальцы ног.
BuvinJ
1
Используя терминологию MySQL, @@GLOBALпеременные становятся еще более «глобальными» и коварными. Они пересекают сессии! @variablesимеют «сессионный охват», так что, по крайней мере, они остаются в таком ограничении. Однако на любом нормальном языке это то, что вы называете «глобальной» областью действия (когда они пересекают функции и т. Д.). Концепцию MySQL «глобальный», возможно, следует назвать «универсальной», поскольку она выходит за пределы процесса, выполняющего ее. «Глобальный» обычно не может сделать это на стандартном языке, поскольку процессы не разделяют пространство памяти. Это связано с устойчивой (против изменчивой) тенденцией SQL.
Ответы:
MySQL
имеет понятие пользовательских переменных .Они являются свободно типизированными переменными, которые могут быть инициализированы где-то в сеансе и сохраняют свое значение до завершения сеанса.
Они дополнены
@
знаком, как это:@var
Вы можете инициализировать эту переменную с помощью
SET
оператора или внутри запроса:Когда вы разрабатываете хранимую процедуру в
MySQL
, вы можете передать входные параметры и объявить локальные переменные:Эти переменные не содержат префиксов.
Разница между переменной процедуры и пользовательской переменной, специфичной для сеанса, заключается в том, что переменная процедуры инициализируется повторно при
NULL
каждом вызове процедуры, в то время как переменная, специфичная для сеанса, не имеет значения:Как видите,
var2
(переменная процедуры) переинициализируется при каждом вызове процедуры, в то время как@var2
( сеансу) - нет.(В дополнение к пользовательским переменным, MySQL также имеет некоторые предопределенные «системные переменные», которые могут быть «глобальными переменными», такими как
@@global.port
или «переменные сеанса», такие как@@session.sql_mode
; эти «переменные сеанса» не связаны с пользовательским определением сеанса. переменные.)источник
SELECT @@version;
Например. Это также причина, почему использованиеDELIMITER @@
не очень хорошая идея.@
против нет?:=
и есть одно существенное различие, заключающееся в=
том, что он:=
везде работает как оператор присваивания переменной, а=
работает только вSET
выражениях и везде является оператором сравнения. Таким образомSELECT @var = 1 + 1;
, @var останется неизменным и вернет логическое значение (1 или 0 в зависимости от текущего значения @var), аSELECT @var := 1 + 1;
изменит @var на 2 и вернет 2.В MySQL
@variable
указывает пользовательскую переменную . Вы можете определить свой собственный.Вне хранимых программ, a
variable
, без@
, является системной переменной , которую вы не можете определить самостоятельно.Область действия этой переменной - весь сеанс. Это означает, что, хотя ваше соединение с базой данных существует, переменная все еще может использоваться.
Это отличается от MSSQL, где переменная будет доступна только в текущем пакете запросов (хранимая процедура, сценарий или другое). Он не будет доступен в другой партии в том же сеансе.
источник
SET @@a = 'test';
, ср. dev.mysql.com/doc/refman/5.1/ru/set-statement.html@@
. Так , например,set@@my_var=1
,set@@session.my_var=1
иset session my_var=1
не будет работать , потому чтоmy_var
это не система переменной, в то время как мы можем сделатьset@@big_tables=1
,set@@session.big_tables=1
иset session big_tables=1
потому , чтоbig_tables
это системная переменная.var2
это переменная без@
префикса, но это не системная переменная: это переменная процедуры. Это разрешено, потому что он находится в хранимой процедуре (она же хранимая программа) Вне хранимых процедур переменная без@
является системной переменной.MSSQL требует, чтобы переменные внутри процедур были DECLAREd, и люди используют синтаксис @Variable (DECLARE @TEXT VARCHAR (25) = 'text'). Кроме того, MS допускает объявления в любом блоке процедуры, в отличие от mySQL, который требует всех DECLARE вверху.
Хотя это хорошо для командной строки, я чувствую, что использование «set = @variable» в хранимых процедурах в MySQL рискованно. Там нет области видимости и переменные живут за пределами границ области видимости. Это похоже на объявление переменных в JavaScript без префикса «var», которые затем являются глобальным пространством имен и создают неожиданные коллизии и перезаписи.
Я надеюсь, что хорошие люди в mySQL разрешат DECLARE @Variable на различных уровнях блоков в хранимой процедуре. Обратите внимание на @ (на знак). Префикс @ sign помогает отделить имена переменных от имен столбцов таблицы, поскольку они часто совпадают. Конечно, всегда можно добавить префикс «v» или «l_», но знак @ - это удобный и лаконичный способ, чтобы имя переменной совпадало со столбцом, из которого вы, возможно, извлекаете данные, не забивая их.
MySQL является новым для хранимых процедур, и они сделали хорошую работу для своей первой версии. Будет приятно посмотреть, где они принимают форму, и посмотреть, как развиваются аспекты серверной части языка.
источник
В принципе, я использую UserDefinedVariables (с префиксом @) в хранимых процедурах. Это облегчает жизнь, особенно когда мне нужны эти переменные в двух или более хранимых процедурах. Просто когда мне нужна переменная только в ОДНОЙ хранимой процедуре, тогда я использую системную переменную (без префикса @).
@Xybo: я не понимаю, почему использование @variables в StoredProcedures должно быть рискованным. Не могли бы вы объяснить, немного «проще» и «границы» (для меня, как новичка)?
источник
@@GLOBAL
переменные становятся еще более «глобальными» и коварными. Они пересекают сессии!@variables
имеют «сессионный охват», так что, по крайней мере, они остаются в таком ограничении. Однако на любом нормальном языке это то, что вы называете «глобальной» областью действия (когда они пересекают функции и т. Д.). Концепцию MySQL «глобальный», возможно, следует назвать «универсальной», поскольку она выходит за пределы процесса, выполняющего ее. «Глобальный» обычно не может сделать это на стандартном языке, поскольку процессы не разделяют пространство памяти. Это связано с устойчивой (против изменчивой) тенденцией SQL.