Поделиться через


DECLARE @local_variable (Transact-SQL)

Применимо к:SQL ServerБаза данных Azure SQLУправляемый экземпляр Azure SQLAzure Synapse AnalyticsСистема платформы аналитики (PDW)Конечная точка SQL аналитики в Microsoft FabricХранилище в Microsoft FabricБаза данных SQL в Microsoft Fabric

Переменные объявляются в тексте пакета или процедуры с DECLARE инструкцией и назначаются значения с помощью инструкции SET или SELECT инструкции. При помощи этой инструкции можно объявлять переменные курсоров для использования в других инструкциях. После объявления все переменные инициализированы как NULL, если значение не указано в рамках объявления.

Соглашения о синтаксисе Transact-SQL

Syntax

Следующий синтаксис предназначен для SQL Server и Базы данных SQL Azure:

DECLARE
{
  { @local_variable [AS] data_type [ = value ] }
  | { @cursor_variable_name CURSOR }
| { @table_variable_name [AS] <table_type_definition> }
} [ , ...n ]

<table_type_definition> ::=
    TABLE ( { <column_definition> | <table_constraint> | <table_index> } } [ , ...n ] )

<column_definition> ::=
    column_name { scalar_data_type | AS computed_column_expression }
    [ COLLATE collation_name ]
    [ [ DEFAULT constant_expression ] | IDENTITY [ (seed, increment ) ] ]
    [ ROWGUIDCOL ]
    [ <column_constraint> ]
    [ <column_index> ]

<column_constraint> ::=
{
    [ NULL | NOT NULL ]
    { PRIMARY KEY | UNIQUE }
      [ CLUSTERED | NONCLUSTERED ]
      [ WITH FILLFACTOR = fillfactor
        | WITH ( < index_option > [ , ...n ] )
      [ ON { filegroup | "default" } ]
  | [ CHECK ( logical_expression ) ] [ , ...n ]
}

<column_index> ::=
    INDEX index_name [ CLUSTERED | NONCLUSTERED ]
    [ WITH ( <index_option> [ , ... n ] ) ]
    [ ON { partition_scheme_name (column_name )
         | filegroup_name
         | default
         }
    ]
    [ FILESTREAM_ON { filestream_filegroup_name | partition_scheme_name | "NULL" } ]

<table_constraint> ::=
{
    { PRIMARY KEY | UNIQUE }
      [ CLUSTERED | NONCLUSTERED ]
      ( column_name [ ASC | DESC ] [ , ...n ]
        [ WITH FILLFACTOR = fillfactor
        | WITH ( <index_option> [ , ...n ] )
  | [ CHECK ( logical_expression ) ] [ , ...n ]
}

<table_index> ::=
{
    {
      INDEX index_name  [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ]
         (column_name [ ASC | DESC ] [ , ... n ] )
    | INDEX index_name CLUSTERED COLUMNSTORE
    | INDEX index_name [ NONCLUSTERED ] COLUMNSTORE ( column_name [ , ... n ] )
    }
    [ WITH ( <index_option> [ , ... n ] ) ]
    [ ON { partition_scheme_name ( column_name )
         | filegroup_name
         | default
         }
    ]
    [ FILESTREAM_ON { filestream_filegroup_name | partition_scheme_name | "NULL" } ]
}

<index_option> ::=
{
  PAD_INDEX = { ON | OFF }
  | FILLFACTOR = fillfactor
  | IGNORE_DUP_KEY = { ON | OFF }
  | STATISTICS_NORECOMPUTE = { ON | OFF }
  | STATISTICS_INCREMENTAL = { ON | OFF }
  | ALLOW_ROW_LOCKS = { ON | OFF }
  | ALLOW_PAGE_LOCKS = { ON | OFF }
  | OPTIMIZE_FOR_SEQUENTIAL_KEY = { ON | OFF }
  | COMPRESSION_DELAY = { 0 | delay [ Minutes ] }
  | DATA_COMPRESSION = { NONE | ROW | PAGE | COLUMNSTORE | COLUMNSTORE_ARCHIVE }
       [ ON PARTITIONS ( { partition_number_expression | <range> }
       [ , ...n ] ) ]
  | XML_COMPRESSION = { ON | OFF }
      [ ON PARTITIONS ( { <partition_number_expression> | <range> }
      [ , ...n ] ) ] ]
}

Следующий синтаксис предназначен для Azure Synapse Analytics и Parallel Data Warehouse и Microsoft Fabric:

DECLARE
{ { @local_variable [AS] data_type } [ = value [ COLLATE <collation_name> ] ] } [ , ...n ]

Arguments

@ local_variable

Имя переменной. Имена переменных должны начинаться с символа @. Имена локальных переменных должны соответствовать правилам для идентификаторов.

  • data_type

    Любой системный тип данных, определяемый пользователем табличный тип среды CLR или псевдоним типа данных. Переменная не может иметь тип данных text, ntext или image.

    Дополнительные сведения о системных типах данных см. в разделе "Типы данных". Дополнительные сведения о пользовательских типах или типах данных псевдонимов среды CLR см. в статье CREATE TYPE.

  • = ценность

    Подставляет значение переменной. Значение может быть константой или выражением, но должно совпадать с объявленным типом переменной или явно преобразовываться в этот тип. Дополнительные сведения см. в разделе "Выражения".

@ cursor_variable_name

Имя переменной курсора. Имена переменных курсора должны начинаться с символа @ и должны соответствовать правилам именования идентификаторов.

  • CURSOR

    Указывает, что переменная является локальной переменной курсора.

  • @ table_variable_name

    Имя переменной типа table. Имена переменных должны начинаться с символа @ и соответствовать правилам именования идентификаторов.

  • <table_type_definition>

    Определяет тип данных table. Декларация таблицы включает определения столбцов, имен, типов данных и ограничений. Допустимы только типы PRIMARY KEYограничений : , UNIQUENULLи CHECK. Псевдоним типа данных не может использоваться как скалярный тип данных столбца, если к этому столбцу привязано правило или значение по умолчанию.

<table_type_definition>

Подмножество сведений, используемых для определения таблицы.CREATE TABLE Сюда включены элементы и наиболее существенные определения. Дополнительные сведения см. в статье CREATE TABLE.

  • n

    Заполнитель, указывающий на то, что могут быть заданы несколько переменных и им могут быть присвоены значения. При объявлениитабличных переменных переменная таблицы должна быть единственной переменной, объявленной в инструкции DECLARE .

column_name

Имя столбца в таблице.

  • scalar_data_type

    Указывает, что столбец имеет скалярный тип данных.

  • computed_column_expression

    Выражение, определяющее значение вычисляемого столбца. Он вычисляется из выражения с помощью других столбцов в той же таблице. Например, вычисляемый столбец может иметь определение cost AS price * qty. Выражение может быть некомпьютерным именем столбца, константой, встроенной функцией, переменной или любым сочетанием этих параметров, подключенных к одному или нескольким операторам. Выражение не может быть вложенным запросом или определяемой пользователем функцией. Выражение не может ссылаться на определяемый пользователем тип данных CLR.

[ COLLATE collation_name ]

Задает параметры сортировки для столбца. collation_name может быть либо именем сортировки Windows, либо именем сортировки SQL, и применимо только для столбцов char, varchar, text, nchar, nvarchar и ntext данных. Если этот аргумент не указан, столбцу назначаются либо параметры сортировки определяемого пользователем типа данных (если столбец принадлежит к определяемому пользователем типу данных), либо параметры сортировки текущей базы данных.

Дополнительные сведения о именах параметров сортировки Windows и SQL см. в разделе COLLATE.

DEFAULT

Указывает значение, присваиваемое столбцу в случае отсутствия явно заданного значения при вставке. DEFAULT определения можно применять к любым столбцам, кроме столбцов, определенных как метка времени или свойство IDENTITY . DEFAULT определения удаляются при удалении таблицы. Только константное значение, например символьная строка; системная функция, например ; SYSTEM_USER()или NULL может использоваться в качестве стандартной функции. Для обеспечения совместимости с более ранними версиями SQL Server можно назначить DEFAULTимя ограничения.

  • constant_expression

    Константой NULLили системной функцией, используемой в качестве значения по умолчанию для столбца.

IDENTITY

Указывает, что новый столбец является столбцом идентификаторов. При добавлении новой строки в таблицу SQL Server предоставляет уникальное добавочное значение для столбца. Столбцы удостоверений обычно используются с PRIMARY KEY ограничениями для использования в качестве уникального идентификатора строки для таблицы. Свойство IDENTITY можно назначить крошечным, smallint, int, десятичным(p,0)или числовым(p,0) столбцам. Для каждой таблицы можно создать только один столбец идентификаторов. Привязанные значения по умолчанию и DEFAULT ограничениям нельзя использовать с столбцом удостоверений. Необходимо указывать либо оба значения seed и increment, либо ни тот, ни другой. Если ничего не указано, применяется значение по умолчанию (1,1).

  • seed

    Значение, используемое для первой строки, загружаемой в таблицу.

  • increment

    Значение, добавляемое к значению идентификатора предыдущей загруженной строки.

ROWGUIDCOL

Указывает, что новый столбец является столбцом глобального уникального идентификатора строки. В качестве столбца можно указать только один столбец uniqueidentifier для каждой ROWGUIDCOL таблицы. Свойство ROWGUIDCOL может быть назначено только столбцу uniqueidentifier .

NULL | НЕ NULL

Указывает, является ли значение null допустимым в переменной. Значение по умолчанию — NULL.

ПЕРВИЧНЫЙ КЛЮЧ

Ограничение, которое с помощью уникального индекса требует целостности сущностей для данного столбца или столбцов. Для каждой таблицы можно создать только одно PRIMARY KEY ограничение.

UNIQUE

Ограничение, которое с помощью уникального индекса обеспечивает целостность сущностей для данного столбца или столбцов. Таблица может иметь несколько UNIQUE ограничений.

CLUSTERED | НЕКЛАСТЕРИЗОВАННЫЙ

Указывает, что кластеризованный или некластеризованный индекс создается для PRIMARY KEY или UNIQUE ограничения. PRIMARY KEY ограничения используются CLUSTEREDи UNIQUE используются NONCLUSTEREDограничения.

CLUSTERED можно указать только для одного ограничения. Если CLUSTERED для UNIQUE ограничения задано и PRIMARY KEY ограничение также указано, PRIMARY KEY используется NONCLUSTERED.

CHECK

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

  • logical_expression

    Логическое выражение, возвращающее TRUE или FALSE.

<index_option>

Указывает один или более параметров индекса. Для переменных table нельзя явно создавать индексы, при этом статистика для переменных table не сохраняется. В SQL Server 2014 (12.x) появился синтаксис, позволяющий создавать определенные типы индексов, встроенные в определение таблицы. С помощью этого синтаксиса можно создавать индексы для табличных переменных в рамках определения таблицы. В некоторых случаях производительность может улучшиться с помощью временных таблиц, которые обеспечивают полную поддержку индекса и статистику.

Полное описание этих параметров см. в разделе CREATE TABLE.

Табличные переменные и расчетное количество строк

Для переменных Table не предусмотрена статистика распределения. Во многих случаях оптимизатор создает план запроса на предположение, что переменная таблицы имеет нулевые строки или одну строку. Дополнительные сведения см. в описании типа данных таблицы — ограничения.

По этой причине следует проявлять осторожность относительно использования табличной переменной, если ожидается большое число строк (больше 100). Рассмотрите один из следующих вариантов:

  • Временные таблицы могут быть лучшим решением, чем переменные таблицы, если это возможно для того, чтобы число строк было больше (больше 100).

  • Для запросов, которые присоединяются к переменной таблицы с другими таблицами, используйте RECOMPILE указание, которое приводит к тому, что оптимизатор использует правильную кратность для переменной таблицы.

  • В Базе данных SQL Azure и начиная с SQL Server 2019 (15.x) функция отложенной компиляции табличной переменной распространяет оценки кратности, основанные на фактических количествах строк табличных переменных, что обеспечивает более точное число строк для оптимизации плана выполнения. Дополнительные сведения см. в статье Интеллектуальная обработка запросов в базах данных SQL.

Remarks

Переменные часто используются в пакете или процедуре в качестве счетчиков для WHILEблока LOOPили для IF...ELSE блока.

Переменные могут использоваться только в выражениях, но не вместо имен объектов или ключевых слов. Чтобы создать динамические инструкции SQL, используйте EXECUTE.

Областью локальной переменной является пакет, в котором она объявлена.

Табличная переменная необязательно является резидентной. В случае нехватки памяти страницы, относящиеся к табличной переменной, можно перенести в базу данных tempdb.

Встроенный индекс можно определить в табличной переменной.

На переменную курсора, которая в настоящее время содержит назначенный ей курсор, можно ссылаться в качестве источника из:

  • CLOSE утверждение
  • DEALLOCATE утверждение
  • FETCH утверждение
  • OPEN утверждение
  • Позиционированные или DELETE операторы UPDATE
  • SET CURSOR оператор переменной (справа)

Во всех этих инструкциях SQL Server формирует ошибку, если переменная курсора, на которую они ссылаются, существует, но не содержит курсора, назначенного ей в настоящее время. Если переменной курсора, на которую производится ссылка, не существует, сервер SQL Server формирует ту же ошибку, что и для необъявленной переменной другого типа.

Переменная курсора:

  • Может быть целью типа курсора или другой переменной курсора. Дополнительные сведения см. в разделе SET @local_variable.

  • Можно ссылаться в качестве целевого объекта выходного параметра курсора в EXECUTE инструкции, если для переменной курсора не назначен курсор.

  • Должна рассматриваться в качестве указателя на курсор.

Examples

Примеры кода в этой статье используют AdventureWorks2025 базу данных или AdventureWorksDW2025 пример базы данных, которую можно скачать на домашней странице microsoft SQL Server Samples and Community Projects .

A. Использование DECLARE

В следующем примере используется локальная переменная с именем @find для получения контактных данных для всех имен семейств, начиная с Man.

USE AdventureWorks2022;
GO

DECLARE @find AS VARCHAR (30);
/* Also allowed:
DECLARE @find VARCHAR(30) = 'Man%';
*/

SET @find = 'Man%';

SELECT p.LastName,
       p.FirstName,
       ph.PhoneNumber
FROM Person.Person AS p
     INNER JOIN Person.PersonPhone AS ph
         ON p.BusinessEntityID = ph.BusinessEntityID
WHERE LastName LIKE @find;

Вот результирующий набор.

LastName            FirstName               Phone
------------------- ----------------------- -------------------------
Manchepalli         Ajay                    1 (11) 500 555-0174
Manek               Parul                   1 (11) 500 555-0146
Manzanares          Tomas                   1 (11) 500 555-0178

B. Использование DECLARE с двумя переменными

В следующем примере извлекаются имена представителей продаж Adventure Works Cycles, которые находятся на территории продаж Северная Америка n и имеют по крайней мере $2000 000 в продажах в течение года.

USE AdventureWorks2022;
GO

SET NOCOUNT ON;
GO

DECLARE @Group AS NVARCHAR (50), @Sales AS MONEY;

SET @Group = N'North America';
SET @Sales = 2000000;
SET NOCOUNT OFF;

SELECT FirstName,
       LastName,
       SalesYTD
FROM Sales.vSalesPerson
WHERE TerritoryGroup = @Group
      AND SalesYTD >= @Sales;

C. Объявление переменной таблицы типов

В следующем примере создается переменная table , в которой хранятся значения, указанные в OUTPUT предложении инструкции UPDATE . Две следующие инструкции SELECT возвращают значения в табличную переменную @MyTableVar, а результаты операции обновления — в таблицу Employee. Результаты в столбце INSERTED.ModifiedDate отличаются от значений в столбце ModifiedDate таблицы Employee. Это связано с тем, что для таблицы AFTER UPDATE определен триггер ModifiedDate, обновляющий значение Employee до текущей даты. Однако столбцы, возвращенные из OUTPUT, отражают состояние данных перед срабатыванием триггеров. Дополнительные сведения см. в предложении OUTPUT.

USE AdventureWorks2022;
GO

DECLARE @MyTableVar TABLE (
    EmpID INT NOT NULL,
    OldVacationHours INT,
    NewVacationHours INT,
    ModifiedDate DATETIME);

UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25
OUTPUT INSERTED.BusinessEntityID,
    DELETED.VacationHours,
    INSERTED.VacationHours,
    INSERTED.ModifiedDate
INTO @MyTableVar;

--Display the result set of the table variable.
SELECT EmpID,
       OldVacationHours,
       NewVacationHours,
       ModifiedDate
FROM @MyTableVar;
GO

--Display the result set of the table.
--Note that ModifiedDate reflects the value generated by an
--AFTER UPDATE trigger.
SELECT TOP (10) BusinessEntityID,
                VacationHours,
                ModifiedDate
FROM HumanResources.Employee;
GO

D. Объявление переменной таблицы типов с встроенными индексами

В указанном ниже примере создается переменная table с кластеризованным встроенным индексом и двумя некластеризованными встроенными индексами.

DECLARE @MyTableVar TABLE (
    EmpID INT NOT NULL,
    PRIMARY KEY CLUSTERED (EmpID),
    UNIQUE NONCLUSTERED (EmpID),
    INDEX CustomNonClusteredIndex NONCLUSTERED (EmpID));
GO

Указанный ниже запрос возвращает сведения об индексах, созданных в предыдущем запросе.

SELECT * FROM tempdb.sys.indexes
WHERE object_id < 0;
GO

E. Объявление переменной определяемого пользователем типа таблицы

Следующий пример демонстрирует создание параметра, возвращающего табличное значение, или табличной переменной с именем @LocationTVP. Для этого шага требуется соответствующий определяемый пользователем тип LocationTableTypeтаблицы.

Дополнительные сведения о создании определяемого пользователем типа таблицы см. в статье CREATE TYPE. Дополнительные сведения о параметрах с табличным значением см. в разделе Use table-valued parameters (Database Engine).

DECLARE @LocationTVP AS LocationTableType;

Примеры: Azure Synapse Analytics и система платформы аналитики (PDW)

F. Использование DECLARE

В следующем примере используется локальная переменная с именем @find для получения контактных данных для всех имен семейств, начиная с Walt.

-- Uses AdventureWorks
DECLARE @find AS VARCHAR (30);
/* Also allowed:
DECLARE @find VARCHAR(30) = 'Man%';
*/

SET @find = 'Walt%';

SELECT LastName,
       FirstName,
       Phone
FROM DimEmployee
WHERE LastName LIKE @find;

G. Использование DECLARE с двумя переменными

В следующем примере извлекаются переменные, чтобы указать имена сотрудников в DimEmployee таблице.

DECLARE @lastName AS VARCHAR (30),
    @firstName AS VARCHAR (30);

SET @lastName = 'Walt%';
SET @firstName = 'Bryan';

SELECT LastName,
       FirstName,
       Phone
FROM DimEmployee
WHERE LastName LIKE @lastName
      AND FirstName LIKE @firstName;