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을 만들려면 네 부분으로 구성된 linked_server.catalog.schema.object 형식의 이름을 사용하여 SELECT 문의 FROM 절을 사용하여 원본 테이블을 지정합니다. 또는 FROM 절에 OPENQUERY 함수나 OPENDATASOURCE 함수를 사용하여 원격 데이터 원본을 지정할 수도 있습니다.
데이터 형식
기존 ID 열을 새 테이블로 선택하여 넣을 때 다음 조건 중 만족하는 것이 없는 경우 새 열은 IDENTITY 속성을 상속합니다.
SELECT 문이 조인, GROUP BY 절 또는 집계 함수를 포함합니다.
UNION을 사용하여 여러 SELECT 문을 조인합니다.
선택 목록에서 ID 열이 두 번 이상 나열됩니다.
ID 열이 식의 일부입니다.
ID 열을 원격 데이터 원본에서 가져옵니다.
위의 조건 중 만족하는 것이 있으면 열은 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) 데이터 형식이 2GB로 제한됩니다. FILESTREAM BLOB이 이 값을 초과하면 오류 7119가 발생하고 해당 문이 중지됩니다.
원본 테이블에 정의된 인덱스, 제약 조건 및 트리거는 새 테이블로 전송되지 않으며 SELECT...INTO 문에 지정할 수도 없습니다. 이러한 개체가 필요하면 SELECT...INTO 문을 실행한 후에 개체를 만들어야 합니다.
ORDER BY 절을 지정한다고 해서 행이 지정된 순서로 삽입되는 것은 아닙니다.
로깅 동작
SELECT...INTO의 로깅 양은 데이터베이스에 적용되는 복구 모델에 따라 달라집니다. 단순 복구 모델 또는 대량 로그 복구 모델에서는 대량 작업이 최소 로깅됩니다. 최소 로깅의 경우 테이블을 만든 후 INSERT 문을 사용하여 해당 테이블을 채우는 것보다 SELECT… INTO 문을 사용하는 것이 보다 효율적일 수 있습니다. 자세한 내용은 최소 로깅 가능한 작업을 참조하십시오.
사용 권한
대상 데이터베이스에서 CREATE TABLE 권한이 필요합니다.
예
1. 여러 원본에서 열을 지정하여 테이블 만들기
다음 예에서는 다양한 직원 관련 테이블 및 주소 관련 테이블에서 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
2. 최소 로깅을 사용하여 행 삽입
다음 예에서는 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
3. 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';
4. 원격 데이터 원본에서 열을 지정하여 테이블 만들기
다음 예에서는 원격 데이터 원본의 로컬 서버에 새 테이블을 만드는 세 가지 방법을 보여 줍니다. 먼저 원격 데이터 원본과의 링크를 만듭니다. 그런 다음 첫 번째 SELECT...INTO 문의 FROM 절과 두 번째 SELECT...INTO 문의 OPENQUERY 함수에 연결된 서버 이름 MyLinkServer,를 지정합니다. 세 번째 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