В SQL важно сразу уточнить, о какой СУБД идет речь. В SQL Server пользовательские глобальные переменные в привычном смысле не объявляются. Есть локальные переменные с одним символом @, системные значения с двумя символами @@, временные таблицы и контекст сессии
В MySQL есть пользовательские переменные с @name и системные переменные @@global.name, но это уже другой синтаксис и другое поведение
Быстрый ответ для SQL Server
Локальная переменная объявляется через DECLARE:
DECLARE @UserId INT;
SET @UserId = 10;
SELECT *
FROM users
WHERE id = @UserId;
Такая переменная живет только в текущем пакете, процедуре или скрипте. Она не становится глобальной и не доступна всем пользователям сервера
Системные значения SQL Server выглядят так:
SELECT @@SERVERNAME AS server_name;
SELECT @@VERSION AS sql_version;
SELECT @@ROWCOUNT AS last_rows_count;
Их нельзя объявить вручную как свои глобальные переменные. Это встроенные значения SQL Server
Почему нельзя просто объявить глобальную переменную
База данных работает с множеством пользователей и запросов одновременно. Если бы любой скрипт мог создать общую переменную для всех сессий, возникли бы проблемы с гонками, безопасностью и непредсказуемым состоянием
Поэтому в SQL Server состояние обычно хранят иначе:
- в таблице настроек
- во временной таблице
- в параметре процедуры
- в
SESSION_CONTEXT - в переменной внутри процедуры
- в настройках приложения, а не в базе
Как хранить значение в рамках сессии
Если нужно передать значение внутри одной пользовательской сессии, можно использовать SESSION_CONTEXT
EXEC sys.sp_set_session_context
@key = N'current_user_id',
@value = 42;
SELECT SESSION_CONTEXT(N'current_user_id') AS current_user_id;
Это не глобальная переменная для всего сервера. Значение живет в контексте конкретного подключения
Такой подход полезен, когда приложение подключается к базе и хочет передать в процедуры идентификатор текущего пользователя или режим работы
Как хранить значение для всех пользователей
Если значение должно быть общим для системы, обычно создают таблицу настроек:
CREATE TABLE app_settings (
setting_name NVARCHAR(100) PRIMARY KEY,
setting_value NVARCHAR(4000)
);
INSERT INTO app_settings (setting_name, setting_value)
VALUES (N'default_currency', N'RUB');
SELECT setting_value
FROM app_settings
WHERE setting_name = N'default_currency';
Такое решение проще контролировать: можно выдавать права, менять значение транзакционно, вести аудит и не зависеть от внутреннего состояния сессии
Переменные в MySQL
В MySQL пользовательская переменная выглядит так:
SET @user_id = 10;
SELECT *
FROM users
WHERE id = @user_id;
Системные переменные можно читать на уровне сессии или глобального уровня:
SELECT @@session.time_zone;
SELECT @@global.max_connections;
Но даже здесь не стоит заменять переменными нормальную структуру данных. Для настроек приложения надежнее использовать таблицу
Мини-практика
Проверьте разницу между локальной переменной и системным значением в SQL Server:
DECLARE @Limit INT = 5;
SELECT TOP (@Limit)
name,
create_date
FROM sys.databases
ORDER BY create_date DESC;
SELECT @@SERVERNAME AS server_name;
Первое значение вы объявили сами. Второе значение SQL Server возвращает из своей системной информации
Частые ошибки
- Думать, что
@@означает переменную, которую можно создать вручную - Использовать локальную переменную там, где нужно хранить настройку между запусками
- Хранить бизнес-настройки в сессионном контексте, хотя они должны лежать в таблице
- Путать синтаксис SQL Server и MySQL
- Ожидать, что переменная из одного окна SSMS будет доступна в другом окне
Что почитать дальше по SQL
Если нужен общий маршрут по теме, откройте рубрику SQL. Для соседних задач пригодятся эти разборы:
- ALTER TABLE в SQL: как добавить, изменить и удалить столбец
- BETWEEN SQL: как выбрать значения в диапазоне
- CREATE TABLE SQL: как создать таблицу запросом
- CSV в SQL: как загрузить файл в базу данных



