適用対象: SQL Server
Azure SQL Database
Azure SQL Managed Instance
Microsoft Fabric SQL Database
テーブルに設定される行の値式のセットを指定します。 Transact-SQL テーブル値コンストラクターを使用すると、単一の DML ステートメントで複数行のデータを指定できます。 テーブル値コンストラクターは、VALUES
ステートメントのINSERT ... VALUES
句として、または USING
ステートメントの MERGE
句または FROM
句の派生テーブルとして指定できます。
構文
VALUES ( <row value expression list> ) [ ,...n ]
<row value expression list> ::=
{<row value expression> } [ ,...n ]
<row value expression> ::=
{ DEFAULT | NULL | expression }
引数
価値観
行の値式のリストを指定します。 各リストはかっこで囲み、コンマで区切る必要があります。
各リストで指定されている値の数が同じであり、値はテーブル内の列と同じ順序で並んでいる必要があります。 テーブル内の各列に対応する値を指定するか、列リストを使用して各入力値を格納する列を明示的に指定する必要があります。
デフォルト
データベース エンジンによって、列に対して定義されている既定値が読み込まれます。 列に既定値が存在せず、列で null 値が許可されている場合は、 NULL
が挿入されます。
DEFAULT
が ID 列に対して無効です。 テーブル値コンストラクターで指定した場合、 DEFAULT
は INSERT
ステートメントでのみ使用できます。
式 (expression)
定数、変数、または式。 式に EXECUTE
ステートメントを含めることはできません。
制限事項
派生テーブルとして使用した場合、行数に制限はありません。
VALUES
ステートメントのINSERT ... VALUES
句として使用する場合、1,000 行の制限があります。 行数が最大値を超えると、エラー 10738 が返されます。 1,000 行を超える行を挿入するには、次のいずれかの方法を使用します。
複数の
INSERT
ステートメントを作成します。派生テーブルを使用します。
bcp ユーティリティ、.NET SqlBulkCopy クラス、OPENROWSET BULK、または BULK INSERT ステートメントを使用して、データを一括インポートします。
単一のスカラー値だけが行の値式として使用できます。 複数の列が関係するサブクエリは行の値式として使用できません。 たとえば、次のコードでは、3 番目の行の値式のリストに複数の列を持つサブクエリが含まれているため、構文エラーが返されます。
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
ただし、このステートメントは、サブクエリ内の各列を個別に指定するように書き直すことができます。 次の例では、MyProducts
テーブルに 3 つの行が正常に挿入されます。
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
データ型
複数行の INSERT
ステートメントで指定された値は、 UNION ALL
構文のデータ型変換プロパティに従います。 これにより、一致しない型が、より 高いデータ型の優先順位の型に暗黙的に変換されます。 暗黙的な変換がサポートされていない場合は、エラーが返されます。 たとえば、次のステートメントでは、整数値と文字値が、char 型の列に挿入されます。
CREATE TABLE dbo.t (a INT, b CHAR);
GO
INSERT INTO dbo.t VALUES (1,'a'), (2, 1);
GO
INSERT
ステートメントを実行すると、データ型の優先順位は整数が文字よりも高い型であることを示しているため、SQL Server は 'a' を整数に変換しようとします。 変換は失敗して、エラーが返されます。 必要に応じて値を明示的に変換することで、このようなエラーを回避できます。 たとえば、上記のステートメントは次のように記述できます。
INSERT INTO dbo.t VALUES (1,'a'), (2, CONVERT(CHAR,1));
例
A。 複数行のデータを挿入する
次の例では、テーブル dbo.Departments
を作成し、テーブル値コンストラクターを使用して、そのテーブルに 5 行を挿入します。 すべての列の値が指定され、テーブルの列と同じ順序で並んでいるため、列名を列リストで指定する必要はありません。
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. DEFAULT 値と NULL 値を持つ複数の行を挿入する
次の例では、テーブル値コンストラクターを使用して行をテーブルに挿入するときに、 DEFAULT
と NULL
を指定する方法を示します。
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. FROM 句で派生テーブルとして複数の値を指定する
次の例では、テーブル値コンストラクターを使用して、FROM
ステートメントの SELECT
句で複数の値を指定します。
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. MERGE ステートメントで派生ソース テーブルとして複数の値を指定する
次の例では、 MERGE
を使用して、行を更新または挿入して SalesReason
テーブルを変更します。 ソース テーブルのNewName
の値がターゲット テーブル (Name
) のSalesReason
列の値と一致すると、ターゲット テーブルのReasonType
列が更新されます。
NewName
の値が一致しない場合は、ソース行が対象テーブルに挿入されます。 ソース テーブルは、Transact-SQL テーブル値コンストラクターを使用して、ソース テーブルに対して複数の行を指定する派生テーブルです。
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. 1,000 行を超える行を挿入する
次の例では、派生テーブルとしてテーブル値コンストラクターを使用する方法を示します。 これにより、1 つのテーブル値コンストラクターから 1,000 行を超える行を挿入できます。
CREATE TABLE dbo.Test ([Value] INT);
INSERT INTO dbo.Test ([Value])
SELECT drvd.[NewVal]
FROM (VALUES (0), (1), (2), (3), ..., (5000)) drvd([NewVal]);