INTO 句 (Transact-SQL)
SELECT...INTO は、既定のファイル グループに新しいテーブルを作成し、クエリの結果得られた行をそのテーブルに挿入します。SELECT の完全な構文を確認するには、「SELECT (Transact-SQL)」を参照してください。
構文
[ INTO new_table ]
引数
new_table
新しいテーブルの名前を指定します。このテーブルは選択リストで指定した列とデータ ソースから選択された行を基に作成されます。new_table の形式は、選択リスト内の式を評価することによって決まります。new_table 内の列は、選択リストの指定順に作成されます。new_table 内の各列の名前、データ型、NULL 値の許容属性、値は、選択リスト内の対応する式と同じになります。列の IDENTITY プロパティは、「解説」の「ID 列の使用」に示されている条件に当てはまる場合を除いて転送されます。
同じ SQL Server インスタンスの別のデータベースにテーブルを作成するには、new_table を database.schema.table_name の形式で完全修飾名として指定します。
リモート サーバーに new_table を作成することはできませんが、new_table にリモート データ ソースのデータを設定することはできます。リモート ソース テーブルから new_table を作成するには、SELECT ステートメントの FROM 句で、linked_server.catalog.schema.object という形式の 4 部構成の名前を使用してソース テーブルを指定します。FROM 句で OPENQUERY 関数か OPENDATASOURCE 関数を使用してリモート データ ソースを指定することもできます。
データ型
既存の ID 列が新しいテーブルに選択された場合は、次の条件のいずれかが満たされている場合を除き、新しい列には IDENTITY プロパティが継承されます。
SELECT ステートメントに、結合、GROUP BY 句、集計関数のいずれかが含まれている。
複数の SELECT ステートメントが UNION を使用して結合されている。
ID 列が選択リストに 2 回以上指定されている。
ID 列が式の一部である。
ID 列がリモート データ ソースから取得されている。
これらの条件が 1 つでも満たされている場合は、列に IDENTITY プロパティは継承されず、代わりに NOT NULL として作成されます。新しいテーブルに ID 列が必要であるものの使用できる列がない場合や、ソースの ID 列とは異なるシード値や増分値が必要な場合は、選択リストで IDENTITY 関数を使用してその列を定義します。以下の「例」の「IDENTITY 関数を使用して ID 列を作成する」を参照してください。
制限事項と制約事項
INTO 句には、次の制限事項と制約事項が適用されます。
テーブル変数やテーブル値パラメータを新しいテーブルとして指定することはできません。
ソース テーブルがパーティション分割されている場合でも、SELECT...INTO を使用してパーティション テーブルを作成することはできません。SELECT...INTO では、ソース テーブルのパーティション構成が使用されず、新しいテーブルが既定のファイル グループに作成されます。パーティション テーブルに行を挿入するには、まずパーティション テーブルを作成してから INSERT INTO...SELECT FROM ステートメントを使用する必要があります。
リストに計算列が指定されている場合、新しいテーブル内の対応する列は計算列にはなりません。新しい列の値は、SELECT...INTO が実行された時点の計算値になります。
SELECT...INTO は、COMPUTE と共に使用することはできません。
FILESTREAM 属性は新しいテーブルに転送されません。FILESTREAM BLOB がコピーされ、varbinary(max) BLOB として新しいテーブルに格納されます。FILESTREAM 属性がない場合、varbinary(max) データ型は 2 GB までに制限されます。FILESTREAM BLOB がこの値を超えると、エラー 7119 が発生して、ステートメントが中止されます。
ソース テーブルに定義されているインデックス、制約、およびトリガは、新しいテーブルに転送されません。SELECT...INTO ステートメントで指定することもできません。これらのオブジェクトが必要な場合は、SELECT...INTO ステートメントの実行後に作成する必要があります。
ORDER BY 句を指定しても、行が指定した順序どおりに挿入されるかどうかは保証されません。
ログ記録の動作
SELECT...INTO のログ記録量は、データベースに対して有効な復旧モデルによって異なります。単純復旧モデルまたは一括ログ復旧モデルでは、一括操作は最小限しかログに記録されません。最小ログ記録を使用する場合は、テーブルを作成してから INSERT ステートメントでそのテーブルにデータを設定するより、SELECT...INTO ステートメントを使用する方が効率的である可能性があります。詳細については、「最小ログ記録が可能な操作」を参照してください。
権限
対象となるデータベースの CREATE TABLE 権限が必要です。
例
A. 複数のソースの列を指定してテーブルを作成する
次の例では、各種の従業員関連テーブルと住所関連テーブルから 7 つの列を選択して、テーブル dbo.EmployeeAddresses を作成します。
USE AdventureWorks;
GO
SELECT c.FirstName, c.LastName, e.Title, a.AddressLine1, a.City, sp.Name AS [State/Province], a.PostalCode
INTO dbo.EmployeeAddresses
FROM Person.Contact AS c
JOIN HumanResources.Employee AS e ON e.ContactID = c.ContactID
JOIN HumanResources.EmployeeAddress AS ea ON ea.EmployeeID = e.EmployeeID
JOIN Person.Address AS a on a.AddressID = ea.AddressID
JOIN Person.StateProvince as sp ON sp.StateProvinceID = a.StateProvinceID;
GO
B. 最小ログ記録を使用して行を挿入する
次の例では、テーブル dbo.NewProducts を作成し、Production.Product テーブルの行を挿入します。この例では、AdventureWorks データベースの復旧モデルが FULL に設定されていると想定しています。したがって、最小ログ記録が使用されるようにするために、行を挿入する前に AdventureWorks データベースの復旧モデルを BULK_LOGGED に設定し、SELECT...INTO ステートメントの後に FULL に戻しています。これにより、SELECT...INTO ステートメントが使用するトランザクション ログの領域が最小化され、ステートメントが効率的に実行されるようになります。
USE AdventureWorks;
GO
IF OBJECT_ID ('dbo.NewProducts', 'U') IS NOT NULL
DROP TABLE dbo.NewProducts;
GO
ALTER DATABASE AdventureWorks SET RECOVERY BULK_LOGGED;
GO
SELECT * INTO dbo.NewProducts
FROM Production.Product
WHERE ListPrice > $25
AND ListPrice < $100;
GO
ALTER DATABASE AdventureWorks SET RECOVERY FULL;
GO
C. IDENTITY 関数を使用して ID 列を作成する
次の例では、IDENTITY 関数を使用して、新しいテーブル Person.USAddress に ID 列を作成します。この操作が必要になるのは、テーブルを定義する SELECT ステートメントに結合が含まれているため、IDENTITY プロパティが新しいテーブルに転送されないからです。IDENTITY 関数で、ソース テーブル Person.Address の AddressID 列とは異なるシード値と増分値が指定されていることに注意してください。
USE AdventureWorks;
GO
-- Determine the IDENTITY status of the source column AddressID.
SELECT OBJECT_NAME(object_id) AS TableName, name AS column_name, is_identity, seed_value, increment_value
FROM sys.identity_columns
WHERE name = 'AddressID';
-- Create a new table with columns from the existing table Person.Address. A new IDENTITY
-- column is created by using the IDENTITY function.
SELECT IDENTITY (int, 100, 5) AS AddressID,
a.AddressLine1, a.City, b.Name AS State, a.PostalCode
INTO Person.USAddress
FROM Person.Address AS a
INNER JOIN Person.StateProvince AS b ON a.StateProvinceID = b.StateProvinceID
WHERE b.CountryRegionCode = N'US';
-- Verify the IDENTITY status of the AddressID columns in both tables.
SELECT OBJECT_NAME(object_id) AS TableName, name AS column_name, is_identity, seed_value, increment_value
FROM sys.identity_columns
WHERE name = 'AddressID';
D. リモート データ ソースの列を指定してテーブルを作成する
次の例は、ローカル サーバーで新しいテーブルをリモート データ ソースから作成するための 3 つの方法を示しています。最初にリモート データ ソースへのリンクを作成した後、リンク サーバー名の MyLinkServer を、1 つ目の SELECT...INTO ステートメントの FROM 句と、2 つ目の SELECT...INTO ステートメントの OPENQUERY 関数に指定しています。3 つ目の SELECT...INTO ステートメントでは、OPENDATASOURCE 関数を使用して、リンク サーバー名を使用する代わりに直接リモート データ ソースを指定しています。
USE master;
GO
-- Create a link to the remote data source.
-- Specify a valid server name for @datasrc as 'server_name' or 'server_name\instance_name'.
EXEC sp_addlinkedserver @server = N'MyLinkServer',
@srvproduct = N' ',
@provider = N'SQLNCLI',
@datasrc = N'server_name',
@catalog = N'AdventureWorks';
GO
USE AdventureWorks;
GO
-- Specify the remote data source in the FROM clause using a four-part name
-- in the form linked_server.catalog.schema.object.
SELECT *
INTO dbo.Departments
FROM MyLinkServer.AdventureWorks.HumanResources.Department
GO
-- Use the OPENQUERY function to access the remote data source.
SELECT *
INTO dbo.DepartmentsUsingOpenQuery
FROM OPENQUERY(MyLinkServer, 'SELECT *
FROM AdventureWorks.HumanResources.Department');
GO
-- Use the OPENDATASOURCE function to specify the remote data source.
-- Specify a valid server name for Data Source using the format server_name or server_name\instance_name.
SELECT *
INTO dbo.DepartmentsUsingOpenDataSource
FROM OPENDATASOURCE('SQLNCLI',
'Data Source=server_name;Integrated Security=SSPI')
.AdventureWorks.HumanResources.Department;
GO