MySQL: @variable против переменной. Какая разница?

451

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

@variable

и

variable

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

Теги:
variables

4 ответа

513
Лучший ответ

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, эти "переменные сеанса", не связаны с определенными пользователем определенными пользователем переменными.)

  • 41
    Также обратите внимание, что доступны глобальные переменные: см. SELECT @@version; например. Это также причина, почему использование DELIMITER @@ не очень хорошая идея.
  • 12
    это создает новые вопросы для новичков ... есть ли разница между "var = var" и "var: = var", как в вашем примере?
Показать ещё 23 комментария
66

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

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

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

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

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

  • 2
    Не следует путать с переменными сеанса, которые имеют сокращение SET @@a = 'test'; ср. dev.mysql.com/doc/refman/5.1/en/set-statement.html
  • 0
    @RobM, они называются системными переменными, а не переменными сеанса.
Показать ещё 7 комментариев
9

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

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

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

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

3

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

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

  • 3
    Это нарушает основные принципы разработки программного обеспечения. Пожалуйста, не пишите другую строку кода, пока вы точно не знаете, что такое область действия, и почему использование глобальных переменных - вообще ужасная идея. Когда я взял 101 класс программирования, насколько я помню, использование global для почти чего-либо привело бы к автоматическому «F». Есть особые исключения, но, как правило, просто не делайте этого!
  • 0
    Зачем? - @Variables абсолютно обычны в каждой книге MySQL.
Показать ещё 8 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню