Clausola INTO (Transact-SQL)

SELECT…INTO crea una nuova tabella nel filegroup predefinito e vi inserisce le righe restituite dalla query. Per visualizzare la sintassi SELECT completa, vedere SELECT (Transact-SQL).

Icona di collegamento a un argomentoConvenzioni della sintassi Transact-SQL

Sintassi

[ INTO new_table ]

Argomenti

  • new_table
    Specifica il nome della nuova tabella da creare in base alle colonne dell'elenco di selezione e alle righe scelte dall'origine dati.

    Il formato di new_table viene determinato tramite la valutazione delle espressioni nell'elenco di selezione. Le colonne di new_table vengono create nell'ordine indicato nell'elenco di selezione. A ogni colonna di new_table vengono assegnati lo stesso nome, lo stesso tipo di dati, il supporto dei valori Null e lo stesso valore dell'espressione corrispondente nell'elenco di selezione. La proprietà IDENTITY di una colonna viene trasferita, tranne nelle condizioni definite in "Utilizzo di colonne Identity" nella sezione Osservazioni.

    Per creare la tabella in un altro database della stessa istanza di SQL Server, specificare new_table come nome completo nel formato database.schema.table_name.

    Non è possibile creare new_table in un server remoto. È tuttavia possibile popolare new_table da un'origine dati remota. Per creare new_table da una tabella di origine remota, specificare la tabella di origine utilizzando un nome in quattro parti nel formato server_collegato.catalogo.schema.oggetto nella clausola FROM dell'istruzione SELECT. In alternativa, è possibile utilizzare la funzione OPENQUERY o OPENDATASOURCE nella clausola FROM per specificare l'origine dati remota.

Tipi di dati

Quando viene selezionata una colonna Identity esistente in una nuova tabella, la nuova colonna eredita la proprietà IDENTITY, a meno che non si verifichi una delle seguenti condizioni:

  • L'istruzione SELECT include un join, una clausola GROUP BY o una funzione di aggregazione.

  • Più istruzioni SELECT sono unite in join tramite l'operatore UNION.

  • La colonna Identity è inclusa più di una volta nell'elenco di selezione.

  • La colonna Identity fa parte di un'espressione.

  • La colonna Identity proviene da un'origine dei dati remota.

Se una di queste condizioni risulta vera, la colonna viene creata come colonna NOT NULL, anziché ereditare la proprietà IDENTITY. Se una colonna Identity è richiesta nella nuova tabella ma tale colonna non è disponibile o si desidera un valore di inizializzazione o di incremento diverso della colonna Identity di origine, definire la colonna nell'elenco di selezione utilizzando la funzione IDENTITY. Vedere "Creazione di una colonna Identity tramite la funzione IDENTITY" nella sezione Esempi più avanti.

Limitazioni e restrizioni

Alla clausola INTO si applicano le limitazioni e restrizioni seguenti:

  • Non è possibile specificare una variabile di tabella o un parametro con valori di tabella come nuova tabella.

  • Non è possibile utilizzare SELECT…INTO per creare una tabella partizionata, anche quando la tabella di origine è partizionata. Lo schema di partizione della tabella di origine non viene utilizzato in SELECT...INTO. La nuova tabella viene invece creata nel filegroup predefinito. Per inserire righe in una tabella partizionata, per prima cosa è necessario creare la tabella partizionata, quindi utilizzare l'istruzione INSERT INTO...SELECT FROM.

  • Quando nell'elenco di selezione è presente una colonna calcolata, la colonna corrispondente della nuova tabella non è di tipo calcolato. I valori della nuova colonna corrispondono ai valori calcolati quando è stata eseguita l'istruzione SELECT...INTO.

  • L'istruzione SELECT...INTO non può essere utilizzata quando viene specificata l'opzione COMPUTE.

  • L'attributo FILESTREAM non viene trasferito nella nuova tabella. Gli oggetti BLOB FILESTREAM vengono copiati e archiviati nella nuova tabella come oggetti BLOB di tipo varbinary(max). Senza l'attributo FILESTREAM, il tipo di dati varbinary(max) è soggetto al limite di 2 GB. Se un oggetto BLOB FILESTREAM supera questo valore, viene generato l'errore 7119 e l'istruzione viene arrestata.

  • Indici, vincoli e trigger definiti nella tabella di origine non vengono trasferiti alla nuova tabella e non possono essere specificati nell'istruzione SELECT...INTO. Se questi oggetti sono necessari, è necessario crearli dopo aver eseguito l'istruzione SELECT...INTO.

  • La specifica della clausola ORDER BY non garantisce che le righe vengano inserite nell'ordine specificato.

Comportamento di registrazione

La quantità di registrazioni per SELECT INTO dipende dal modello di recupero attivato per il database. Nel modello di recupero con registrazione minima o in quello con registrazione minima delle operazioni bulk, per tali operazioni la registrazione prevista è quella minima. Con la registrazione minima, l'utilizzo dell'istruzione SELECT... INTO può essere più efficiente della creazione di una tabella e del popolamento della stessa con un'istruzione INSERT. Per ulteriori informazioni, vedere Operazioni per cui è possibile eseguire la registrazione minima.

Autorizzazioni

È necessaria l'autorizzazione CREATE TABLE nel database di destinazione.

Esempi

A. Creazione di una tabella specificando colonne provenienti da più origini

Nell'esempio seguente viene creata la tabella dbo.EmployeeAddresses selezionando sette colonne da diverse tabelle relative a dipendenti e indirizzi.

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. Inserimento di righe utilizzando la registrazione minima

Nell'esempio seguente viene creata la tabella dbo.NewProducts, in cui vengono inserite righe della tabella Production.Product. L'esempio presuppone che il modello di recupero del database AdventureWorks sia impostato su FULL. Per assicurare l'utilizzo della registrazione minima, il modello di recupero del database AdventureWorks viene impostato su BULK_LOGGED prima che le righe vengano inserite e reimpostato su FULL dopo l'istruzione SELECT...INTO. In tal modo, si assicura l'utilizzo da parte dell'istruzione SELECT...INTO di uno spazio minimo nel log delle transazioni con risultati efficienti.

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. Creazione di una colonna Identity tramite la funzione IDENTITY

Nell'esempio seguente viene utilizzata la funzione IDENTITY per creare una colonna Identity nella nuova tabella Person.USAddress. Questa operazione è necessaria perché l'istruzione SELECT che definisce la tabella contiene un join che fa in modo che la proprietà IDENTITY non venga trasferita nella nuova tabella. Si noti che il valore di inizializzazione e il valore di incremento specificati nella funzione IDENTITY sono diversi da quelli della colonna AddressID nella tabella di origine Person.Address.

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. Creazione di una tabella specificando colonne provenienti da un'origine dei dati remota

Nell'esempio seguente vengono illustrati tre metodi per creare una nuova tabella nel server locale da un'origine dati remota. L'esempio inizia con la creazione di un collegamento all'origine dati remota. Il nome del server collegato, MyLinkServer, viene specificato nella clausola FROM della prima istruzione SELECT...INTO e nella funzione OPENQUERY della seconda istruzione SELECT...INTO. La terza istruzione SELECT...INTO utilizza la funzione OPENDATASOURCE che specifica direttamente l'origine dei dati remota anziché utilizzare il nome del server collegato.

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