Dela via


DEKLARERA @local_variable (Transact-SQL)

Gäller för:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalysplattformssystem (PDW)SQL-analysslutpunkt i Microsoft FabricLager i Microsoft FabricSQL-databas i Förhandsversion av Microsoft Fabric

Variabler deklareras i brödtexten i en batch eller procedur med -instruktionen DECLARE och tilldelas värden med hjälp av antingen en SET - eller SELECT -instruktion. Markörvariabler kan deklareras med den här instruktionen och användas med andra markörrelaterade instruktioner. Efter deklarationen initieras alla variabler som NULL, såvida inte ett värde anges som en del av deklarationen.

Transact-SQL syntaxkonventioner

Syntax

Följande syntax gäller för SQL Server och Azure SQL Database:

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 ] ) ] ]
}

Följande syntax gäller för Azure Synapse Analytics och Parallel Data Warehouse och Microsoft Fabric:

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

Arguments

@ local_variable

Namnet på en variabel. Variabelnamn måste börja med ett (@) tecken. Lokala variabelnamn måste följa reglerna för identifierare.

  • data_type

    Valfri användardefinierad tabelltyp som tillhandahålls av system, CLR (Common Language Runtime) eller aliasdatatyp. En variabel får inte vara av datatypen text, ntext eller bild .

    Mer information om systemdatatyper finns i Datatyper. Mer information om ANVÄNDARDEFINIERADE CLR-typer eller aliasdatatyper finns i SKAPA TYP.

  • = värde

    Tilldelar ett värde till variabeln in-line. Värdet kan vara en konstant eller ett uttryck, men det måste antingen matcha variabeldeklarationstypen eller implicit konverteras till den typen. Mer information finns i Uttryck.

@ cursor_variable_name

Namnet på en markörvariabel. Markörvariabelnamn måste börja med ett vid (@) tecken och följa reglerna för identifierare.

  • MARKÖR

    Anger att variabeln är en lokal markörvariabel.

  • @ table_variable_name

    Namnet på en variabel av typen tabell. Variabelnamn måste börja med ett at-tecken (@) och överensstämma med reglerna för identifierare.

  • <table_type_definition>

    Definierar tabelldatatypen . Tabelldeklarationen innehåller kolumndefinitioner, namn, datatyper och begränsningar. De enda villkorstyper som tillåts är PRIMARY KEY, UNIQUE, NULLoch CHECK. En aliasdatatyp kan inte användas som en kolumnskalardatatyp om en regel eller standarddefinition är bunden till typen.

<table_type_definition>

En delmängd av information som används för att definiera en tabell i CREATE TABLE. Element och viktiga definitioner ingår här. Mer information finns i SKAPA TABELL.

  • n

    En platshållare som anger att flera variabler kan anges och tilldelas värden. När du deklarerar tabellvariabler måste tabellvariabeln vara den enda variabel som deklareras i -instruktionen.DECLARE

column_name

Namnet på kolumnen i tabellen.

  • scalar_data_type

    Anger att kolumnen är en skalär datatyp.

  • computed_column_expression

    Ett uttryck som definierar värdet för en beräknad kolumn. Den beräknas från ett uttryck med hjälp av andra kolumner i samma tabell. En beräknad kolumn kan till exempel ha definitionen cost AS price * qty. Uttrycket kan vara ett icke-inberäknat kolumnnamn, konstant, inbyggd funktion, variabel eller någon kombination av dessa alternativ som är anslutna av en eller flera operatorer. Uttrycket får inte vara en underfråga eller en användardefinierad funktion. Uttrycket kan inte referera till en CLR-användardefinierad typ.

[ COLLATE collation_name ]

Anger sortering för kolumnen. collation_name kan vara antingen ett Windows-sorteringsnamn eller ett SQL-sorteringsnamn och gäller endast för kolumner av datatyperna char, varchar, text, nchar, nvarchar och ntext . Om den inte anges tilldelas kolumnen antingen sortering av den användardefinierade datatypen (om kolumnen är av en användardefinierad datatyp) eller sortering av den aktuella databasen.

Mer information om Windows- och SQL-sorteringsnamnen finns i COLLATE.

DEFAULT

Anger det värde som anges för kolumnen när ett värde inte uttryckligen anges under en infogning. DEFAULT definitioner kan tillämpas på alla kolumner, förutom kolumner som definierats som tidsstämpel eller med egenskapen IDENTITY . DEFAULT definitioner tas bort när tabellen tas bort. Endast ett konstant värde, till exempel en teckensträng; en systemfunktion, till exempel en SYSTEM_USER(); eller NULL kan användas som standard. För att upprätthålla kompatibilitet med tidigare versioner av SQL Server kan ett villkorsnamn tilldelas till en DEFAULT.

  • constant_expression

    En konstant, NULLeller en systemfunktion som används som standardvärde för kolumnen.

IDENTITY

Anger att den nya kolumnen är en identitetskolumn. När en ny rad läggs till i tabellen ger SQL Server ett unikt inkrementellt värde för kolumnen. Identitetskolumner används ofta med PRIMARY KEY begränsningar för att fungera som unik radidentifierare för tabellen. Egenskapen IDENTITY kan tilldelas till kolumnerna tinyint, smallint, int, decimal(p,0) eller numeriska(p,0). Endast en identitetskolumn kan skapas per tabell. Bundna standardvärden och DEFAULT begränsningar kan inte användas med en identitetskolumn. Du måste ange både fröet och inkrementet, eller ingetdera. Om inget av dem anges är standardvärdet (1,1).

  • seed

    Det värde som används för den första raden som läses in i tabellen.

  • increment

    Det inkrementella värdet som lades till i identitetsvärdet för den föregående raden som lästes in.

ROWGUIDCOL

Anger att den nya kolumnen är en global unik identifierarkolumn för rad. Endast en unikidentifierarkolumn per tabell kan anges som ROWGUIDCOL kolumn. Egenskapen ROWGUIDCOL kan endast tilldelas till en unikidentifierarkolumn .

NULL | INTE NULL

Anger om null tillåts i variabeln. Standardvärdet är NULL.

PRIMÄRNYCKEL

En begränsning som framtvingar entitetsintegritet för en viss kolumn eller kolumner via ett unikt index. Endast en PRIMARY KEY begränsning kan skapas per tabell.

UNIQUE

En begränsning som ger entitetsintegritet för en viss kolumn eller kolumner via ett unikt index. En tabell kan ha flera UNIQUE begränsningar.

KLUSTRAD | NONCLUSTERED

Ange att ett grupperat index eller ett icke-grupperat index skapas för villkoret PRIMARY KEY eller UNIQUE . PRIMARY KEY begränsningar använder CLUSTERED, och UNIQUE begränsningar använder NONCLUSTERED.

CLUSTERED kan endast anges för en begränsning. Om CLUSTERED anges för en UNIQUE begränsning och en PRIMARY KEY begränsning också anges används PRIMARY KEYNONCLUSTERED.

CHECK

En begränsning som framtvingar domänintegritet genom att begränsa de möjliga värden som kan anges i en kolumn eller kolumner.

  • logical_expression

    Ett logiskt uttryck som returnerar TRUE eller FALSE.

<index_option>

Anger ett eller flera indexalternativ. Index kan inte skapas explicit i tabellvariabler och ingen statistik sparas för tabellvariabler. SQL Server 2014 (12.x) introducerade syntax som gör att du kan skapa vissa indextyper internt med tabelldefinitionen. Med den här syntaxen kan du skapa index för tabellvariabler som en del av tabelldefinitionen. I vissa fall kan prestandan förbättras genom att använda tillfälliga tabeller i stället, vilket ger fullständigt indexstöd och statistik.

En fullständig beskrivning av de här alternativen finns i SKAPA TABELL.

Tabellvariabler och raduppskattningar

Tabellvariabler har inte distributionsstatistik. I många fall skapar optimeraren en frågeplan utifrån antagandet att tabellvariabeln har noll rader eller en rad. Mer information finns i tabelldatatypen – Begränsningar och begränsningar.

Därför bör du vara försiktig med att använda en tabellvariabel om du förväntar dig ett större antal rader (större än 100). Överväg följande alternativ:

  • Temp-tabeller kan vara en bättre lösning än tabellvariabler när det är möjligt att radantalet är större (större än 100).

  • För frågor som kopplar ihop tabellvariabeln med andra tabeller använder du tipset RECOMPILE , vilket gör att optimeraren använder rätt kardinalitet för tabellvariabeln.

  • I Azure SQL Database och från och med SQL Server 2019 (15.x) sprider funktionen för uppskjuten kompilering av tabellvariabel kardinalitetsuppskattningar som baseras på faktiska antal tabellvariabler, vilket ger ett mer exakt radantal för att optimera körningsplanen. Mer information finns i Intelligent frågebearbetning i SQL-databaser.

Remarks

Variabler används ofta i en batch eller procedur som räknare för WHILE, LOOPeller för ett IF...ELSE block.

Variabler kan endast användas i uttryck, inte i stället för objektnamn eller nyckelord. Om du vill skapa dynamiska SQL-instruktioner använder du EXECUTE.

Omfånget för en lokal variabel är den batch där den deklareras.

En tabellvariabel är inte nödvändigtvis minnesvariabel. Under minnesbelastning kan sidorna som hör till en tabellvariabel skickas ut till tempdb.

Du kan definiera ett infogat index i en tabellvariabel.

En markörvariabel som har tilldelats en markör kan refereras till som en källa i en:

  • CLOSE uttalande
  • DEALLOCATE uttalande
  • FETCH uttalande
  • OPEN uttalande
  • Positionerad DELETE eller UPDATE instruktion
  • SET CURSOR variabeluttryck (till höger)

I alla dessa instruktioner genererar SQL Server ett fel om det finns en refererad markörvariabel men inte har en markör allokerad till sig. Om det inte finns någon refererad markörvariabel genererar SQL Server samma fel som uppstod för en odeklarerad variabel av en annan typ.

En markörvariabel:

  • Kan vara målet för antingen en markörtyp eller en annan markörvariabel. Mer information finns i SET @local_variable.

  • Kan refereras som mål för en utdatamarkörparameter i en EXECUTE instruktion om markörvariabeln inte har en markör tilldelad till sig.

  • Bör betraktas som en pekare till markören.

Examples

Kodexemplen i den här artikeln använder exempeldatabasen AdventureWorks2022 eller AdventureWorksDW2022 som du kan ladda ned från startsidan för Microsoft SQL Server-exempel och Community Projects .

A. Använda DECLARE

I följande exempel används en lokal variabel med namnet @find för att hämta kontaktinformation för alla familjenamn som börjar med 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;

Här är resultatet.

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. Använda DECLARE med två variabler

I följande exempel hämtas namnen på Adventure Works Cycles försäljningsrepresentanter som finns i det nordamerikanska försäljningsområdet och som har minst 2 000 000 USD i försäljning för året.

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. Deklarera en variabel av typen tabell

I följande exempel skapas en table variabel som lagrar de värden som anges i instruktionens OUTPUT sats UPDATE . Två SELECT instruktioner följer som returnerar värdena i @MyTableVar och resultatet av uppdateringsåtgärden i tabellen Employee. Resultatet i INSERTED.ModifiedDate kolumnen skiljer sig från värdena i ModifiedDate kolumnen i Employee tabellen. Det beror på att utlösaren AFTER UPDATE , som uppdaterar värdet ModifiedDate för till det aktuella datumet, har definierats i Employee tabellen. Kolumnerna som returneras från OUTPUT återspegla data innan utlösare utlöses. Mer information finns i OUTPUT-satsen.

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. Deklarera en variabel av typen tabell, med infogade index

I följande exempel skapas en table variabel med ett grupperat infogat index och två icke-grupperade infogade index.

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

Följande fråga returnerar information om indexen som skapades i föregående fråga.

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

E. Deklarera en variabel av användardefinierad tabelltyp

I följande exempel skapas en tabellvärdesparameter eller tabellvariabel med namnet @LocationTVP. Det här steget kräver en motsvarande användardefinierad tabelltyp med namnet LocationTableType.

Mer information om hur du skapar en användardefinierad tabelltyp finns i SKAPA TYP. Mer information om tabellvärdesparametrar finns i Använda tabellvärdesparametrar (databasmotor).

DECLARE @LocationTVP AS LocationTableType;

Exempel: Azure Synapse Analytics and Analytics Platform System (PDW)

F. Använda DECLARE

I följande exempel används en lokal variabel med namnet @find för att hämta kontaktinformation för alla familjenamn som börjar med 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. Använda DECLARE med två variabler

Följande exempel hämtar använder variabler för att ange för- och efternamn för anställda i DimEmployee tabellen.

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;