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).
Convenzioni della sintassi Transact-SQL
Sintassi
[ INTO new_table ]
Argomenti
new_table
Specifica il nome di una nuova tabella da creare in base alle colonne dell'elenco di selezione e alle righe scelte dall'origine dati.Il formato dell'argomento 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 linked_server.catalog.schema.object 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
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.
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
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.
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 richiesti, è possibile crearli dopo avere eseguito l'istruzione SELECT...INTO.
La specifica della clausola ORDER BY non garantisce che le righe vengano inserite nell'ordine specificato.
Quando nell'elenco di selezione è presente una colonna di tipo sparse, la relativa proprietà non viene trasferita nella colonna della nuova tabella. Se questa proprietà è richiesta nella nuova tabella, modificare la definizione di colonna dopo l'esecuzione dell'istruzione SELECT...INTO per includere la proprietà.
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.
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 Log delle transazioni (SQL Server).
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 AdventureWorks2012;
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.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 AdventureWorks2012 sia impostato su FULL. Per assicurare l'utilizzo della registrazione minima, il modello di recupero del database AdventureWorks2012 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 AdventureWorks2012;
GO
IF OBJECT_ID('dbo.NewProducts', 'U') IS NOT NULL
DROP TABLE dbo.NewProducts;
GO
ALTER DATABASE AdventureWorks2012 SET RECOVERY BULK_LOGGED;
GO
SELECT * INTO dbo.NewProducts
FROM Production.Product
WHERE ListPrice > $25
AND ListPrice < $100;
GO
ALTER DATABASE AdventureWorks2012 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 AdventureWorks2012;
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.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'AdventureWorks2012';
GO
USE AdventureWorks2012;
GO
-- Specify the remote data source in the FROM clause using a four-part name
-- in the form linked_server.catalog.schema.object.
SELECT DepartmentID, Name, GroupName, ModifiedDate
INTO dbo.Departments
FROM MyLinkServer.AdventureWorks2012.HumanResources.Department
GO
-- Use the OPENQUERY function to access the remote data source.
SELECT DepartmentID, Name, GroupName, ModifiedDate
INTO dbo.DepartmentsUsingOpenQuery
FROM OPENQUERY(MyLinkServer, 'SELECT *
FROM AdventureWorks2012.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 DepartmentID, Name, GroupName, ModifiedDate
INTO dbo.DepartmentsUsingOpenDataSource
FROM OPENDATASOURCE('SQLNCLI',
'Data Source=server_name;Integrated Security=SSPI')
.AdventureWorks2012.HumanResources.Department;
GO