MySQL: @variable против переменной. Какая разница? - PullRequest
483 голосов
/ 18 июня 2009

В другом вопросе, который я написал, кто-то сказал мне, что есть разница между:

@variable

и

variable

в MySQL. Он также упомянул, как у MSSQL есть пакетная область, а у MySQL есть область сеанса. Может кто-нибудь уточнить это для меня?

Ответы [ 4 ]

602 голосов
/ 18 июня 2009

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;эти «переменные сеанса» не связаны с пользовательскими переменными, специфичными для сеанса.)

69 голосов
/ 18 июня 2009

В MySQL @variable обозначает определяемую пользователем переменную . Вы можете определить свой собственный.

SET @a = 'test';
SELECT @a;

За пределами хранимых программ variable без @ является системной переменной , которую вы не можете определить самостоятельно.

Область действия этой переменной - весь сеанс. Это означает, что, хотя ваше соединение с базой данных существует, переменную все еще можно использовать.

Это отличается от MSSQL, где переменная будет доступна только в текущем пакете запросов (хранимая процедура, сценарий или другое). Он не будет доступен в другом пакете в том же сеансе.

10 голосов
/ 24 марта 2011

MSSQL требует, чтобы переменные внутри процедур были DECLAREd, и люди используют синтаксис @Variable (DECLARE @TEXT VARCHAR (25) = 'text'). Кроме того, MS допускает объявления в любом блоке процедуры, в отличие от mySQL, который требует всех DECLARE вверху.

Хотя это хорошо для командной строки, я чувствую, что использование «set = @variable» в хранимых процедурах в MySQL рискованно. Там нет области видимости и переменные живут за пределами границ области видимости. Это похоже на объявление переменных в JavaScript без префикса «var», которые затем являются глобальным пространством имен и создают неожиданные коллизии и перезаписи.

Я надеюсь, что хорошие люди в mySQL разрешат DECLARE @Variable на различных уровнях блоков в хранимой процедуре. Обратите внимание на @ (на знак). Префикс @ sign помогает отделить имена переменных от имен столбцов таблицы, поскольку они часто совпадают. Конечно, всегда можно добавить префикс «v» или «l_», но знак @ - это удобный и лаконичный способ, чтобы имя переменной совпадало со столбцом, из которого вы, возможно, извлекаете данные, не забивая их.

MySQL является новым для хранимых процедур, и они хорошо поработали над своей первой версией. Будет приятно посмотреть, где они принимают форму, и посмотреть, как развиваются аспекты языка на стороне сервера.

3 голосов
/ 28 апреля 2014

В принципе, я использую UserDefinedVariables (с префиксом @) в хранимых процедурах. Это облегчает жизнь, особенно когда мне нужны эти переменные в двух или более хранимых процедурах. Просто когда мне нужна переменная только в ОДНОЙ хранимой процедуре, тогда я использую системную переменную (без префикса @).

@ Xybo: Я не понимаю, почему использование @variables в StoredProcedures должно быть рискованным. Не могли бы вы объяснить, немного «проще» и «границы» (для меня, как новичка)?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...