MySQL: @variable против переменной. Какая разница?
В другом вопросе я написал, кто-то сказал мне, что есть разница между:
@variable
а также:
variable
в MySQL. Он также упомянул, как у MSSQL есть область действия пакета, а у MySQL есть область действия сеанса. Может кто-нибудь уточнить это для меня?
5 ответов
MySQL
имеет понятие пользовательских переменных.
Они являются свободно типизированными переменными, которые могут быть инициализированы где-то в сеансе и сохраняют свое значение до завершения сеанса.
Они дополнены @
знак, как это: @var
Вы можете инициализировать эту переменную с помощью SET
оператор или внутри запроса:
SET @var = 1
SELECT @var2 := 2
Когда вы разрабатываете хранимую процедуру в MySQL
Вы можете передать входные параметры и объявить локальные переменные:
DELIMITER //
CREATE PROCEDURE prc_test (var INT)
BEGIN
DECLARE var2 INT;
SET var2 = 1;
SELECT var2;
END;
//
DELIMITER ;
Эти переменные не имеют префиксов.
Разница между процедурной переменной и пользовательской переменной, определенной для сеанса, заключается в том, что переменная процедуры повторно инициализируется в NULL
каждый раз, когда процедура вызывается, а переменная, относящаяся к сеансу, не является:
CREATE PROCEDURE prc_test ()
BEGIN
DECLARE var2 INT DEFAULT 1;
SET var2 = var2 + 1;
SET @var2 = @var2 + 1;
SELECT var2, @var2;
END;
SET @var2 = 1;
CALL prc_test();
var2 @var2
--- ---
2 2
CALL prc_test();
var2 @var2
--- ---
2 3
CALL prc_test();
var2 @var2
--- ---
2 4
Как вы видете, var2
(переменная процедуры) переинициализируется при каждом вызове процедуры, в то время как @var2
(переменная, специфичная для сессии) - нет.
(В дополнение к пользовательским переменным MySQL также имеет некоторые предопределенные "системные переменные", которые могут быть "глобальными переменными", такими как @@global.port
или "переменные сеанса", такие как @@session.sql_mode
; эти "переменные сессии" не связаны с пользовательскими переменными, специфичными для сессии.)
В MySQL @variable
указывает пользовательскую переменную. Вы можете определить свой собственный.
SET @a = 'test';
SELECT @a;
За пределами хранимых программ, variable
без @
, является системной переменной, которую вы не можете определить самостоятельно.
Область действия этой переменной - весь сеанс. Это означает, что, хотя ваше соединение с базой данных существует, переменная все еще может использоваться.
Это отличается от MSSQL, где переменная будет доступна только в текущем пакете запросов (хранимая процедура, сценарий или другое). Он не будет доступен в другой партии в том же сеансе.
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 в Stored Procedures должно быть рискованным. Не могли бы вы объяснить, немного "проще" и "границы" (для меня, как новичка)?
Замечание по PL / SQL (Oracle)
Преимущество можно увидеть в Oracle PL / SQL, где эти переменные имеют 3 разных области действия:
- Переменная функции, для которой область действия заканчивается при выходе из функции.
- Переменные тела пакета, определенные в верхней части пакета и вне всех функций, область действия которых - сеанс, а видимость - пакет.
- Переменная пакета, переменная которой - сеанс, а видимость - глобальная.
Мой опыт работы с PL / SQL
Я разработал архитектуру, в которой весь код написан на PL / SQL. Они вызываются из промежуточного программного обеспечения, написанного на Java. Есть два типа промежуточного программного обеспечения. Один для обслуживания звонков от клиента, который также написан на Java. Другой - для звонков из браузера. Клиентские возможности полностью реализованы на JavaScript. Набор команд используется вместо HTML и JavaScript для написания приложения на PL / SQL.
Я искал такое же средство для переноса кодов, написанных на PL / SQL, в другую базу данных. Ближайший, который я нашел, - это Postgres. Но у всех переменных есть функция.
Мнение в отношении MySQL
Я рад видеть, что хотя бы это