Sdílet prostřednictvím


Konstruktor hodnot tabulky (Transact-SQL)

platí pro:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceSQL databáze v Microsoft Fabric

Určuje sadu výrazů hodnot řádků, které se mají vytvořit do tabulky. Konstruktor hodnot tabulky Transact-SQL umožňuje zadání více řádků dat v jednom příkazu DML. Konstruktor hodnoty tabulky lze zadat buď jako VALUES klauzuli INSERT ... VALUES příkazu, nebo jako odvozenou tabulku v USING klauzuli MERGE příkazu nebo FROM klauzuli.

Transact-SQL konvence syntaxe

Syntax

VALUES ( <row value expression list> ) [ ,...n ]   

<row value expression list> ::=  
    {<row value expression> } [ ,...n ]  

<row value expression> ::=  
    { DEFAULT | NULL | expression }  

Arguments

VALUES

Představuje seznamy výrazů hodnot řádků. Každý seznam musí být uzavřený v závorkách a oddělený čárkou.

Počet hodnot zadaných v každém seznamu musí být stejný a hodnoty musí být ve stejném pořadí jako sloupce v tabulce. Je třeba zadat hodnotu pro každý sloupec v tabulce nebo musí seznam sloupců explicitně zadat sloupce pro každou příchozí hodnotu.

DEFAULT

Vynutí databázový stroj vložit výchozí hodnotu definovanou pro sloupec. Pokud pro sloupec neexistuje výchozí hodnota a sloupec povoluje hodnoty null, NULL vloží se. DEFAULT není platný pro sloupec identity. Pokud je zadán v konstruktoru hodnot tabulky, DEFAULT je povolen pouze v INSERT příkazu.

expression

Konstanta, proměnná nebo výraz Výraz nemůže obsahovat EXECUTE příkaz.

Limitations

Při použití jako odvozené tabulky neexistuje žádné omezení počtu řádků.

Při použití jako VALUES klauzule INSERT ... VALUES příkazu je limit 1 000 řádků. Pokud počet řádků překročí maximum, vrátí se chyba 10738. Pokud chcete vložit více než 1 000 řádků, použijte jednu z následujících metod:

Jako výraz hodnoty řádku je povolena pouze jedna skalární hodnota. Poddotaz, který zahrnuje více sloupců, není povolen jako výraz hodnoty řádku. Následující kód například způsobí chybu syntaxe, protože seznam výrazů hodnot třetího řádku obsahuje poddotaz s více sloupci.

USE AdventureWorks2022;  
GO  
CREATE TABLE dbo.MyProducts (Name VARCHAR(50), ListPrice MONEY);  
GO  
-- This statement fails because the third values list contains multiple columns in the subquery.  
INSERT INTO dbo.MyProducts (Name, ListPrice)  
VALUES ('Helmet', 25.50),  
       ('Wheel', 30.00),  
       (SELECT Name, ListPrice FROM Production.Product WHERE ProductID = 720);  
GO  

Příkaz je však možné přepsat zadáním každého sloupce v poddotazu samostatně. Následující příklad úspěšně vloží do tabulky tři řádky MyProducts .

INSERT INTO dbo.MyProducts (Name, ListPrice)  
VALUES ('Helmet', 25.50),  
       ('Wheel', 30.00),  
       ((SELECT Name FROM Production.Product WHERE ProductID = 720),  
        (SELECT ListPrice FROM Production.Product WHERE ProductID = 720));  
GO  

Datové typy

Hodnoty zadané v příkazu s více řádky INSERT se řídí vlastnostmi převodu UNION ALL datového typu syntaxe. Výsledkem je implicitní převod nesrovnaných typů na typ vyšší priority datového typu. Pokud převod není podporovaný implicitní převod, vrátí se chyba. Následující příkaz například vloží celočíselnou hodnotu a hodnotu znaku do sloupce typu char.

CREATE TABLE dbo.t (a INT, b CHAR);  
GO  
INSERT INTO dbo.t VALUES (1,'a'), (2, 1);  
GO  

INSERT Při spuštění příkazu se SQL Server pokusí převést "a" na celé číslo, protože priorita datového typu označuje, že celé číslo je vyšší než znak. Převod selže a vrátí se chyba. Této chybě se můžete vyhnout tak, že hodnoty explicitně převedete podle potřeby. Například předchozí příkaz lze napsat následujícím způsobem.

INSERT INTO dbo.t VALUES (1,'a'), (2, CONVERT(CHAR,1));  

Examples

A. Vložení více řádků dat

Následující příklad vytvoří tabulku dbo.Departments a pak použije konstruktor hodnoty tabulky k vložení pěti řádků do tabulky. Protože jsou zadány hodnoty pro všechny sloupce a jsou uvedeny ve stejném pořadí jako sloupce v tabulce, názvy sloupců nemusí být zadány v seznamu sloupců.

USE AdventureWorks2022;  
GO  
INSERT INTO Production.UnitMeasure  
VALUES (N'FT2', N'Square Feet ', '20080923'), (N'Y', N'Yards', '20080923'),
       (N'Y3', N'Cubic Yards', '20080923');  
GO  

B. Vložení více řádků s hodnotami DEFAULT a NULL

Následující příklad ukazuje určení DEFAULT a NULL při použití konstruktoru hodnoty tabulky k vložení řádků do tabulky.

USE AdventureWorks2022;  
GO  
CREATE TABLE Sales.MySalesReason(  
SalesReasonID int IDENTITY(1,1) NOT NULL,  
Name dbo.Name NULL ,  
ReasonType dbo.Name NOT NULL DEFAULT 'Not Applicable' );  
GO  
INSERT INTO Sales.MySalesReason   
VALUES ('Recommendation','Other'), ('Advertisement', DEFAULT), (NULL, 'Promotion');  

SELECT * FROM Sales.MySalesReason;  

C. Zadání více hodnot jako odvozené tabulky v klauzuli FROM

Následující příklady používají konstruktor hodnoty tabulky k určení více hodnot v FROM klauzuli SELECT příkazu.

SELECT a, b FROM (VALUES (1, 2), (3, 4), (5, 6), (7, 8), (9, 10) ) AS MyTable(a, b);  
GO  
-- Used in an inner join to specify values to return.  
SELECT ProductID, a.Name, Color  
FROM Production.Product AS a  
INNER JOIN (VALUES ('Blade'), ('Crown Race'), ('AWC Logo Cap')) AS b(Name)   
ON a.Name = b.Name;  

D. Zadání více hodnot jako odvozené zdrojové tabulky v příkazu MERGE

Následující příklad používá MERGE k úpravě SalesReason tabulky aktualizací nebo vložením řádků. Pokud hodnota NewName ve zdrojové tabulce odpovídá hodnotě ve Name sloupci cílové tabulky (SalesReason), ReasonType sloupec se aktualizuje v cílové tabulce. Pokud se hodnota NewName neshoduje, vloží se zdrojový řádek do cílové tabulky. Zdrojová tabulka je odvozená tabulka, která používá konstruktor hodnot tabulky Transact-SQL k určení více řádků pro zdrojovou tabulku.

USE AdventureWorks2022;  
GO  
-- Create a temporary table variable to hold the output actions.  
DECLARE @SummaryOfChanges TABLE(Change VARCHAR(20));  

MERGE INTO Sales.SalesReason AS Target  
USING (VALUES ('Recommendation','Other'), ('Review', 'Marketing'), ('Internet', 'Promotion'))  
       AS Source (NewName, NewReasonType)  
ON Target.Name = Source.NewName  
WHEN MATCHED THEN  
UPDATE SET ReasonType = Source.NewReasonType  
WHEN NOT MATCHED BY TARGET THEN  
INSERT (Name, ReasonType) VALUES (NewName, NewReasonType)  
OUTPUT $action INTO @SummaryOfChanges;  

-- Query the results of the table variable.  
SELECT Change, COUNT(*) AS CountPerChange  
FROM @SummaryOfChanges  
GROUP BY Change;  

E. Vložení více než 1 000 řádků

Následující příklad ukazuje použití konstruktoru hodnoty tabulky jako odvozené tabulky. To umožňuje vložit více než 1 000 řádků z konstruktoru jedné hodnoty tabulky.

CREATE TABLE dbo.Test ([Value] INT);  

INSERT INTO dbo.Test ([Value])  
  SELECT drvd.[NewVal]
  FROM   (VALUES (0), (1), (2), (3), ..., (5000)) drvd([NewVal]);