Eseguire la migrazione del codice SQL in SQL Data WarehouseMigrate your SQL code to SQL Data Warehouse

Questo articolo spiega le modifiche del codice che saranno molto probabilmente necessarie quando si esegue la migrazione del codice da un altro database in SQL Data Warehouse.This article explains code changes you will probably need to make when migrating your code from another database to SQL Data Warehouse. Alcune funzionalità di SQL Data Warehouse possono migliorare in modo significativo le prestazioni perché sono progettate per funzionare direttamente in modalità distribuita.Some SQL Data Warehouse features can significantly improve performance as they are designed to work in a distributed fashion. Per mantenere tuttavia le prestazioni e la scalabilità, alcune funzionalità non sono disponibili.However, to maintain performance and scale, some features are also not available.

Limitazioni comuni di T-SQLCommon T-SQL Limitations

L'elenco seguente riepiloga le funzionalità più comuni non supportate in SQL Data Warehouse.The following list summarizes the most common features that SQL Data Warehouse does not support. I collegamenti consentono di accedere a soluzioni alternative per le funzionalità non supportate:The links take you to workarounds for the unsupported features:

Fortunatamente è possibile ovviare alla maggior parte di queste limitazioni.Fortunately most of these limitations can be worked around. Le spiegazioni sono fornite dagli articoli pertinenti a cui viene fatto riferimento più indietro.Explanations are provided in the relevant development articles referenced above.

Funzionalità CTE supportateSupported CTE features

Le espressioni di tabella comune (CTE) sono parzialmente supportate in SQL Data Warehouse.Common table expressions (CTEs) are partially supported in SQL Data Warehouse. Attualmente sono supportate le funzionalità CTE seguenti:The following CTE features are currently supported:

  • Un'espressione CTE può essere specificata in un'istruzione SELECT.A CTE can be specified in a SELECT statement.
  • Un'espressione CTE può essere specificata in un'istruzione CREATE VIEW.A CTE can be specified in a CREATE VIEW statement.
  • Un'espressione CTE può essere specificata in un'istruzione CREATE TABLE AS SELECT (CTAS).A CTE can be specified in a CREATE TABLE AS SELECT (CTAS) statement.
  • Un'espressione CTE può essere specificata in un'istruzione CREATE REMOTE TABLE AS SELECT (CRTAS).A CTE can be specified in a CREATE REMOTE TABLE AS SELECT (CRTAS) statement.
  • Un'espressione CTE può essere specificata in un'istruzione CREATE EXTERNAL TABLE AS SELECT (CETAS).A CTE can be specified in a CREATE EXTERNAL TABLE AS SELECT (CETAS) statement.
  • È possibile fare riferimento a una tabella remota da un'espressione CTE.A remote table can be referenced from a CTE.
  • È possibile fare riferimento a una tabella esterna da un'espressione CTE.An external table can be referenced from a CTE.
  • In un'espressione CTE possono essere definite più definizioni di query CTE.Multiple CTE query definitions can be defined in a CTE.

Limitazioni CTECTE Limitations

Le espressioni di tabella comune presentano alcune limitazioni in SQL Data Warehouse, tra cui:Common table expressions have some limitations in SQL Data Warehouse including:

  • Un'espressione CTE deve essere seguita da una singola istruzione SELECT.A CTE must be followed by a single SELECT statement. Le istruzioni INSERT, UPDATE, DELETE e MERGE non sono supportate.INSERT, UPDATE, DELETE, and MERGE statements are not supported.
  • Un'espressione di tabella comune che include riferimenti a se stessa (un'espressione di tabella comune ricorsiva) non è supportata (vedere la sezione sotto).A common table expression that includes references to itself (a recursive common table expression) is not supported (see below section).
  • Non è consentito specificare più di una clausola WITH in un'espressione CTE.Specifying more than one WITH clause in a CTE is not allowed. Se, ad esempio, CTE_query_definition contiene una sottoquery, tale sottoquery non può contenere una clausola WITH annidata che definisce un'altra CTE.For example, if a CTE_query_definition contains a subquery, that subquery cannot contain a nested WITH clause that defines another CTE.
  • Una clausola ORDER BY non può essere usata in CTE_query_definition, tranne quando viene specificata una clausola TOP.An ORDER BY clause cannot be used in the CTE_query_definition, except when a TOP clause is specified.
  • Quando un'espressione CTE viene usata in un'istruzione che fa parte di un batch, l'istruzione precedente deve essere seguita da un punto e virgola.When a CTE is used in a statement that is part of a batch, the statement before it must be followed by a semicolon.
  • Quando vengono usate in istruzioni preparate da sp_prepare, le espressioni CTE si comporteranno esattamente come le altre istruzioni SELECT in PDW.When used in statements prepared by sp_prepare, CTEs will behave the same way as other SELECT statements in PDW. Tuttavia, se le CTE vengono usate come parte di istruzioni CETAS preparate da sp_prepare, il comportamento può variare rispetto a SQL Server e altre istruzioni PDW per la modalità di implementazione del binding per sp_prepare.However, if CTEs are used as part of CETAS prepared by sp_prepare, the behavior can defer from SQL Server and other PDW statements because of the way binding is implemented for sp_prepare. Se l'istruzione SELECT che fa riferimento alla CTE usa una colonna non corretta che non esiste nella CTE, sp_prepare passa senza rilevare l'errore, che invece viene generato durante sp_execute.If SELECT that references CTE is using a wrong column that does not exist in CTE, the sp_prepare will pass without detecting the error, but the error will be thrown during sp_execute instead.

CTE ricorsiveRecursive CTEs

Le CTE ricorsive non sono supportate in SQL Data Warehouse.Recursive CTEs are not supported in SQL Data Warehouse. La migrazione di CTE ricorsive può essere complessa e il processo ottimale consiste nel suddividere l'operazione in più passaggi.The migration of recursive CTE can be somewhat complex and the best process is to break it into multiple steps. In genere è possibile usare un ciclo e popolare una tabella temporanea mentre si scorrono le query provvisorie ricorsive.You can typically use a loop and populate a temporary table as you iterate over the recursive interim queries. Una volta che viene popolata la tabella temporanea, è quindi possibile restituire i dati come un unico set di risultati.Once the temporary table is populated you can then return the data as a single result set. Un approccio simile è stato usato per risolvere GROUP BY WITH CUBE nell'articolo relativo al raggruppamento per clausola con opzioni di rollup/cubo/set di raggruppamento.A similar approach has been used to solve GROUP BY WITH CUBE in the group by clause with rollup / cube / grouping sets options article.

Funzioni di sistema non supportateUnsupported system functions

Anche alcune funzioni di sistema non sono supportate.There are also some system functions that are not supported. Alcune di queste funzioni principali che in genere vengono usate nel data warehousing sono:Some of the main ones you might typically find used in data warehousing are:

  • NEWSEQUENTIALID()NEWSEQUENTIALID()
  • @@NESTLEVEL()@@NESTLEVEL()
  • @@IDENTITY()@@IDENTITY()
  • @@ROWCOUNT()@@ROWCOUNT()
  • ROWCOUNT_BIGROWCOUNT_BIG
  • ERROR_LINE()ERROR_LINE()

Per alcuni di questi problemi esiste una soluzione alternativa.Some of these issues can be worked around.

Soluzione alternativa @@ROWCOUNT@@ROWCOUNT workaround

Per risolvere la mancanza di supporto per @@ROWCOUNT, creare una stored procedure per recuperare l'ultimo conteggio delle righe da sys.dm_pdw_request_steps e quindi eseguire EXEC LastRowCount dopo un'istruzione DML.To work around lack of support for @@ROWCOUNT, create a stored procedure that will retrieve the last row count from sys.dm_pdw_request_steps and then execute EXEC LastRowCount after a DML statement.

CREATE PROCEDURE LastRowCount AS
WITH LastRequest as 
(   SELECT TOP 1    request_id
    FROM            sys.dm_pdw_exec_requests
    WHERE           session_id = SESSION_ID()
    AND             resource_class IS NOT NULL
    ORDER BY end_time DESC
),
LastRequestRowCounts as
(
    SELECT  step_index, row_count
    FROM    sys.dm_pdw_request_steps
    WHERE   row_count >= 0
    AND     request_id IN (SELECT request_id from LastRequest)
)
SELECT TOP 1 row_count FROM LastRequestRowCounts ORDER BY step_index DESC
;

Passaggi successiviNext steps

Per un elenco completo di tutte le istruzioni T-SQL supportate, vedere Argomenti Transact-SQL.For a complete list of all supported T-SQL statements, see Transact-SQL topics.