Clausola SELECT - INTO (Transact-SQL)

Si applica a: SQL Server database SQL di Azure Istanza gestita di SQL di Azure Azure Synapse Analytics Analytics Platform System (PDW) Warehouse in Microsoft Fabric

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 relative alla sintassi Transact-SQL

Sintassi

[ INTO new_table ]
[ ON filegroup ]

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 usando un nome in quattro parti nel formato linked_server.catalog.schema.object nella clausola FROM dell'istruzione SELECT. In alternativa, è possibile usare la funzione OPENQUERY o OPENDATASOURCE nella clausola FROM per specificare l'origine dati remota.

filegroup
Specifica il nome del filegroup in cui verrà creata la nuova tabella. Il filegroup specificato deve esistere nel database anche se il motore di SQL Server genera un errore.

Si applica a: SQL Server 2016 (13.x) SP2 e versioni successive.

Tipi di dati

L'attributo FILESTREAM non viene trasferito nella nuova tabella. Gli oggetti binari di grandi dimensioni FILESTREAM vengono copiati e archiviati nella nuova tabella come oggetti binari di grandi dimensioni 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 contiene un join.

  • 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.

Osservazioni:

Il funzionamento dell'istruzione SELECT...INTO è costituito da due parti: viene creata la nuova tabella e poi vengono inserite le righe. Ciò significa che verrà eseguito il rollback degli inserimenti non riusciti, ma la nuova tabella (vuota) rimarrà. Se è necessario che l'intera operazione abbia o esito positivo o esito negativo, usare una transazione esplicita.

Il warehouse in Microsoft Fabric non supporta i filegroup. Riferimenti ed esempi in questo articolo ai filegroup non si applicano a Warehouse in Microsoft Fabric.

Limitazioni e restrizioni

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

Non è possibile usare SELECT...INTO per creare una tabella partizionata, anche quando la tabella di origine è partizionata. Lo schema di partizione della tabella di origine non viene usato 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 e quindi usare 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'uso dell'istruzione SELECT...INTO può essere più efficiente della creazione di una tabella e del popolamento della stessa con un'istruzione INSERT. Per altre informazioni, vedere Log delle transazioni (SQL Server).

Le istruzioni SELECT...INTO che contengono funzioni definite dall'utente sono operazioni con registrazione completa. Se le funzioni definite dall'utente usate nell'istruzione SELECT...INTO non eseguono alcuna operazione di accesso ai dati, per tali funzioni è possibile specificare la clausola SCHEMABINDING, che ne imposta la proprietà UserDataAccess derivata su 0. Dopo questa modifica, per le istruzioni SELECT...INTO viene eseguita la registrazione minima. Se l'istruzione SELECT...INTO fa ancora riferimento ad almeno una funzione definita dall'utente la cui proprietà è impostata su 1, l'operazione viene registrata completamente.

Autorizzazioni

Sono richieste l'autorizzazione CREATE TABLE per il database e l'autorizzazione ALTER per lo schema in cui viene creata la tabella.

Esempi

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

Nell'esempio seguente viene creata la tabella dbo.EmployeeAddresses nel database AdventureWorks2022 selezionando sette colonne da varie tabelle correlate ai dipendenti e correlate all'indirizzo.

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. Nell'esempio si presuppone che il modello di recupero del database AdventureWorks2022 sia impostato su FULL. Per garantire l'uso della registrazione minima, il modello di recupero del database AdventureWorks2022 è impostato su BULK_LOGGED prima che le righe vengano inserite e reimpostate su FULL dopo select... Istruzione 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.

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

C. Creazione di una colonna Identity tramite la funzione IDENTITY

Nell'esempio seguente viene usata la funzione IDENTITY per creare una colonna Identity nella nuova tabella Person.USAddress del database AdventureWorks2022. 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.

-- 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.

Si applica a: SQL Server 2008 (10.0.x) e versioni successive.

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'AdventureWorks2022';  
GO  

USE AdventureWorks2022;  
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.AdventureWorks2022.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 AdventureWorks2022.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')  
    .AdventureWorks2022.HumanResources.Department;  
GO  

E. Importare da una tabella esterna creata con PolyBase

Importare dati da Hadoop o dall'archiviazione di Azure in SQL Server per l'archivio permanente. Usare SELECT INTO per importare i dati a cui fa riferimento una tabella esterna per l'archiviazione permanente in SQL Server. Creare un tabella relazionale e quindi creare un indice di archivio colonne nella parte superiore della tabella in un secondo passaggio.

Si applica a: SQL Server.

-- Import data for car drivers into SQL Server to do more in-depth analysis.  
SELECT DISTINCT   
        Insured_Customers.FirstName, Insured_Customers.LastName,   
        Insured_Customers.YearlyIncome, Insured_Customers.MaritalStatus  
INTO Fast_Customers from Insured_Customers INNER JOIN   
(  
        SELECT * FROM CarSensor_Data where Speed > 35   
) AS SensorD  
ON Insured_Customers.CustomerKey = SensorD.CustomerKey  
ORDER BY YearlyIncome;  

F. Copia dei dati da una tabella a un'altra e creazione della nuova tabella in un filegroup specificato

Nell'esempio seguente viene illustrato come creare una nuova tabella come copia di un'altra tabella e come caricarla in un filegroup specificato diverso dal filegroup predefinito dell'utente.

Si applica a: SQL Server 2016 (13.x) SP2 e versioni successive.

ALTER DATABASE [AdventureWorksDW2022] ADD FILEGROUP FG2;
ALTER DATABASE [AdventureWorksDW2022]
ADD FILE
(
NAME='FG2_Data',
FILENAME = '/var/opt/mssql/data/AdventureWorksDW2022_Data1.mdf'
)
TO FILEGROUP FG2;
GO
SELECT * INTO [dbo].[FactResellerSalesXL] ON FG2 FROM [dbo].[FactResellerSales];

Vedi anche

SELECT (Transact-SQL)
Esempi di istruzioni SELECT (Transact-SQL)
INSERT (Transact-SQL)
IDENTITY (Funzione) (Transact-SQL)