В іншому запитанні, який я розмістив, хтось сказав мені, що є різниця між:
@variable
і:
variable
в MySQL. Він також згадав, як MSSQL має пакетний обсяг, а MySQL - обсяг сеансу. Може хтось докладно розробить це для мене?
В іншому запитанні, який я розмістив, хтось сказав мені, що є різниця між:
@variable
і:
variable
в MySQL. Він також згадав, як MSSQL має пакетний обсяг, а MySQL - обсяг сеансу. Може хтось докладно розробить це для мене?
Відповіді:
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
; ці "сесійні змінні" не пов'язані з певними сеансом, визначеними користувачем. змінні.)
SELECT @@version;
., Наприклад. Це також причина, чому використання DELIMITER @@
насправді не є хорошою ідеєю.
@
vs ні?
:=
і =
, і це те, що він :=
працює як оператор присвоєння змінної скрізь, в той час як =
тільки так працює в SET
операторах і є оператором порівняння скрізь. Тож SELECT @var = 1 + 1;
залиште @var незмінним та повернемо булеве значення (1 або 0 залежно від поточного значення @var), тоді як SELECT @var := 1 + 1;
змінимо @var на 2 та повернемося 2.
У MySQL @variable
вказує визначену користувачем змінну . Ви можете визначити своє.
SET @a = 'test';
SELECT @a;
Поза збереженими програмами variable
, без @
, це системна змінна , яку ви не можете самостійно визначити.
Обсяг цієї змінної - весь сеанс. Це означає, що хоча ваш зв’язок із базою даних існує, змінна все ще може бути використана.
Це на відміну від MSSQL, де змінна буде доступна лише в поточній партії запитів (збережена процедура, сценарій чи інше). Він не буде доступний в іншій партії в одному сеансі.
SET @@a = 'test';
, пор. dev.mysql.com/doc/refman/5.1/uk/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) = 'текст'). Крім того, MS дозволяє декларувати в будь-якому блоці процедури, на відміну від mySQL, який вимагає всіх DECLARE вгорі.
Хоча це добре в командному рядку, я вважаю, що використання "set = @variable" у збережених процедурах в mySQL є ризиковим. Немає сфери застосування і змінні живуть за межами меж області. Це схоже на те, що змінні в JavaScript оголошуються без префіксу "var", які потім є глобальним простором імен і створюють несподівані зіткнення та перезаписи.
Я сподіваюся, що хороші люди в mySQL дозволять DECLARE @Variable на різних рівнях блоку в межах збереженої процедури. Помітьте @ (на знак). Префікс знаку @ допомагає відокремити імена змінних від назв стовпців таблиці - оскільки вони часто однакові. Звичайно, завжди можна додати префікс "v" або "l_", але знак @ - це зручний і стислий спосіб, щоб ім'я змінної відповідало стовпцю, з якого ви могли б витягувати дані, не переробляючи їх.
MySQL є новим для збережених процедур, і вони зробили хорошу роботу для своєї першої версії. Буде закликом побачити, де вони приймають його форму тут, і спостерігати за тим, як серверні аспекти мови дозрівають.
В принципі, я використовую UserDefinedVariables (попередньо за допомогою @) в межах збережених процедур. Це полегшує життя, особливо коли мені потрібні ці змінні у двох чи більше збережених процедурах. Якраз тоді, коли мені потрібна змінна лише в межах однієї збереженої процедури, ніж я використовую системну змінну (без попереднього @).
@Xybo: Я не розумію, чому використання @variables у StoredProcedures має бути ризикованим. Не могли б ви пояснити "поле" та "межі" трохи простіше (для мене як для новачків)?
@@GLOBAL
змінні ще більш "глобальні" та підступні. Вони перетинають сесії! @variables
мають "сферу сеансу", тож принаймні вони залишаються обмеженими таким чином. Однак будь-якою нормальною мовою ви називаєте "глобальну" сферу (коли вони перетинають функції тощо). Поняття MySQL "глобального", можливо, слід назвати "універсальним", оскільки воно виходить за межі процесу, що його працює. "Глобальний" не може цього робити звичайною мовою, оскільки процеси не поділяють місця в пам'яті. Це випливає із стійкої (проти мінливої) тенденції SQL.