Cláusula INTO (Transact-SQL)

SELECT…INTO cria uma tabela nova no grupo de arquivos padrão e insere nela as linhas resultantes da consulta. Para exibir a sintaxe completa de SELECT, consulte SELECT (Transact-SQL).

Ícone de vínculo de tópicoConvenções de sintaxe Transact-SQL

Sintaxe

[ INTO new_table ]

Argumentos

  • new_table
    Especifica o nome de uma tabela a ser criada, com base nas colunas da lista de seleção e nas linhas escolhidas na origem dos dados.

    O formato de new_table é determinado pela avaliação das expressões na lista de seleção. As colunas em new_table são criadas na ordem especificada pela lista de seleção. Cada coluna em new_table tem o mesmo nome, tipo de dados, nulidade e valor da expressão correspondente na lista de seleção. A propriedade IDENTITY de uma coluna é transferida, exceto nas condições definidas em "Trabalhando com colunas de identidade" na seção Comentários.

    Para criar a tabela em outro banco de dados na mesma instância do SQL Server, especifique new_table como nome totalmente qualificado no formato database.schema.table_name.

    Não é possível criar new_table em um servidor remoto. No entanto, você pode preencher new_table usando uma fonte de dados remotos. Para criar new_table usando uma tabela de origem remota, especifique a tabela de origem que usa um nome de quatro partes no formulário linked_server.catalog.schema.object na cláusula FROM da instrução SELECT. Como alternativa, é possível usar a função OPENQUERY ou a função OPENDATASOURCE na cláusula FROM para especificar a fonte de dados remotos.

Tipos de dados

O atributo FILESTREAM não é transferido para a nova tabela. FILESTREAM BLOBS são copiados e armazenados na nova tabela como BLOBs varbinary(max). Sem o atributo FILESTREAM, o tipo de dados varbinary(max) tem uma limitação de 2 GB. Se um FILESTREAM BLOB exceder esse valor, o erro 7119 será gerado, e a instrução será interrompida.

Quando uma coluna de identidade existente é selecionada para uma nova tabela, a nova coluna herda a propriedade IDENTITY, a menos que uma das seguintes condições seja verdadeira:

  • A instrução SELECT contém uma junção, cláusula GROUP BY ou função de agregação.

  • Várias instruções SELECT são unidas usando UNION.

  • A coluna de identidade é listada mais de uma vez na lista de seleção.

  • A coluna de identidade faz parte de uma expressão.

  • A coluna de identidade provém de uma fonte de dados remotos.

Se qualquer uma dessas condições for verdadeira, a coluna será criada como NOT NULL em vez de herdar a propriedade IDENTITY. Se uma coluna de identidade for obrigatória na nova tabela mas não estiver disponível, ou você quiser um valor de semente ou de incremento diferente da coluna de identidade de origem, defina a coluna na lista de seleção que usa a função IDENTITY. Consulte "Criando uma coluna de identidade usando a função IDENTITY" na seção Exemplos a seguir.

Limitações e restrições

Não é possível especificar uma variável de tabela ou um parâmetro com valor de tabela como a nova tabela.

Você não pode usar SELECT...INTO para criar uma tabela particionada, mesmo quando a tabela de origem está particionada. SELECT...INTO não usa o esquema de partição da tabela de origem; em vez disso, a nova tabela é criada no grupo de arquivos padrão. Para inserir linhas em uma tabela particionada, é preciso primeiro criar a tabela particionada e depois usar a instrução INSERT INTO...SELECT FROM.

SELECT... INTO não pode ser usada com COMPUTE.

Índices, restrições e gatilhos definidos na tabela de origem não são transferidos para a nova tabela, nem podem ser especificados na instrução SELECT...INTO. Se esses objetos forem obrigatórios, você deverá criá-los depois de executar a instrução SELECT...INTO.

A especificação de uma cláusula ORDER BY não garante que as linhas sejam inseridas na ordem especificada.

Quando uma coluna esparsa é incluída na lista de seleção, a propriedade da coluna esparsa não é transferida para a coluna na nova tabela. Se essa propriedade for necessária na nova tabela, altere a definição da coluna depois de executar o SELECT... INTO instrução para incluir essa propriedade.

Quando uma coluna computada é incluída na lista de seleção, a coluna correspondente na nova tabela não é uma coluna computada. Os valores na nova coluna são os computados no momento em que SELECT...INTO foi executada.

Comportamento de registro em log

A quantidade de registros de SELECT...INTO depende do modelo de recuperação em vigor para o banco de dados. Sob o modelo de recuperação simples ou bulk-logged, operações em massa são registradas minimamente. Com log mínimo, usar a instrução SELECT. INTO pode ser mais eficiente do que criar uma tabela e preenchê-la usando uma instrução INSERT. Para obter mais informações, consulte Operações que podem ser minimamente registradas em log.

Permissões

Exige permissão CREATE DATABASE no banco de dados de destino.

Exemplos

A. Criando uma tabela que especifica colunas de várias origens

O exemplo a seguir cria a tabela dbo.EmployeeAddresses selecionando sete colunas de várias tabelas relacionadas a funcionários e endereços.

USE AdventureWorks2008R2;
GO
SELECT c.FirstName, c.LastName, e.JobTitle, a.AddressLine1, a.City, 
    sp.Name AS [State/Province], a.PostalCode
INTO dbo.EmployeeAddresses
FROM Person.Person AS c
    JOIN HumanResources.Employee AS e 
    ON e.BusinessEntityID = c.BusinessEntityID
    JOIN Person.BusinessEntityAddress AS bea
    ON e.BusinessEntityID = bea.BusinessEntityID
    JOIN Person.Address AS a
    ON bea.AddressID = a.AddressID
    JOIN Person.StateProvince as sp 
    ON sp.StateProvinceID = a.StateProvinceID;
GO

B. Inserindo linhas que usam log mínimo

O exemplo a seguir cria a tabela dbo.NewProducts e insere linhas da tabela Production.Product. O exemplo pressupõe que o modelo de recuperação do banco de dados AdventureWorks2008R2 esteja definido como FULL. Para assegurar um log mínimo, o modelo de recuperação do banco de dados AdventureWorks2008R2 é definido como BULK_LOGGED antes das linhas serem inseridas e redefinidas como FULL após a instrução SELECT...INTO. Esse processo garante que a instrução SELECT... INTO use espaço mínimo no log de transação e seja executada de forma eficiente.

USE AdventureWorks2008R2;
GO
IF OBJECT_ID ('dbo.NewProducts', 'U') IS NOT NULL
    DROP TABLE dbo.NewProducts;
GO
ALTER DATABASE AdventureWorks2008R2 SET RECOVERY BULK_LOGGED;
GO

SELECT * INTO dbo.NewProducts
FROM Production.Product
WHERE ListPrice > $25 
AND ListPrice < $100;
GO
ALTER DATABASE AdventureWorks2008R2 SET RECOVERY FULL;
GO

C. Criando uma coluna de identidade que usa a função IDENTITY

O seguinte exemplo usa a função IDENTITY para criar uma coluna de identidade na nova tabela Person.USAddress. Isso é obrigatório porque a instrução SELECT que define a tabela contém uma junção que faz com que a propriedade IDENTITY não seja transferida para a nova tabela. Observe que os valores de semente e incremento especificados na função IDENTITY são diferentes dos valores da coluna AddressID na tabela de origem Person.Address.

USE AdventureWorks2008R2;
GO
IF OBJECT_ID ('Person.USAddress') IS NOT NULL
DROP TABLE Person.USAddress;
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. Criando uma tabela que especifica colunas de uma fonte de dados remotos

O seguinte exemplo demonstra três métodos para criar uma nova tabela no servidor local de uma fonte de dados remotos. O exemplo começa criando um link para a fonte de dados remotos. O nome do servidor vinculado, MyLinkServer,, é especificado na cláusula FROM da primeira instrução SELECT... INTO e na função OPENQUERY da segunda instrução SELECT... INTO. A terceira instrução SELECT... INTO usa a função OPENDATASOURCE, que especifica a fonte de dados remotos diretamente, em vez de usar o nome do servidor vinculado.

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'AdventureWorks2008R2';
GO
USE AdventureWorks2008R2;
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.AdventureWorks2008R2.HumanResources.Department
GO
-- Use the OPENQUERY function to access the remote data source.
SELECT *
INTO dbo.DepartmentsUsingOpenQuery
FROM OPENQUERY(MyLinkServer, 'SELECT *
               FROM AdventureWorks2008R2.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')
    .AdventureWorks2008R2.HumanResources.Department;
GO