Nel dominio “Prepare and serve data” di DP-600 la domanda ricorrente è sempre la stessa: posso scrivere qui, o solo leggere? Sapere con precisione dove finisce il T-SQL di scrittura è ciò che separa una risposta corretta da un distrattore ben costruito.
Due motori SQL, due contratti diversi
In Microsoft Fabric esistono due superfici T-SQL, entrambe raggiungibili con la stessa connection string TDS e gli stessi strumenti (SSMS, Azure Data Studio, portale):
| Caratteristica | Warehouse | SQL analytics endpoint (Lakehouse) |
|---|---|---|
| SELECT | Sì | Sì |
| INSERT / UPDATE / DELETE / TRUNCATE | Sì | No |
| CREATE TABLE, CTAS, SELECT INTO | Sì | No |
| COPY INTO | Sì | No |
| Transazioni multi-table (ACID, snapshot isolation) | Sì | Solo lettura |
| CREATE VIEW / FUNCTION / PROCEDURE | Sì | Sì (solo logica di lettura) |
| RLS, CLS, dynamic data masking | Sì | Sì |
| Storage sottostante | Delta in OneLake | Delta in OneLake |
Il punto chiave: entrambi scrivono e leggono Delta Lake su OneLake, quindi la differenza non è il formato ma il contratto di scrittura. Il lakehouse si popola con Spark, Dataflow Gen2, pipeline o shortcut; l’endpoint SQL è una proiezione read-only di quelle tabelle Delta.
Cosa puoi comunque fare sull’endpoint
L’endpoint non è “inutile per il DDL”: puoi creare view, funzioni scalari e table-valued e stored procedure purché contengano solo operazioni di lettura. È lì che si costruisce il semantic layer SQL sopra il lakehouse e si applicano le policy di sicurezza a livello di riga e colonna.
Limiti T-SQL del warehouse (i distrattori classici)
Il warehouse non è SQL Server. Non sono supportati:
- Constraint enforced: PRIMARY KEY, UNIQUE e FOREIGN KEY esistono solo come metadati
NOT ENFORCED; l’unicità va garantita dalla pipeline. CHECK constraint non supportati. - IDENTITY, SEQUENCE, colonne calcolate, trigger, indici (nessun clustered/nonclustered index: le performance dipendono da statistiche e ordinamento dei file).
- Tipi di dato legacy:
money,smallmoney,datetime,text/ntext,image,xml,sql_variant, tipi spaziali,rowversion. - Livelli di isolamento diversi da snapshot: niente
READ COMMITTEDcon lock, nienteSERIALIZABLE, nienteREAD UNCOMMITTEDcon semantica di dirty read. - Query cross-workspace: i nomi a tre parti funzionano solo all’interno dello stesso workspace.
Restano invece supportati e vengono spesso sottovalutati: MERGE, CTAS, SELECT INTO, TRUNCATE TABLE, tabelle temporanee di sessione (#temp), VARCHAR(MAX), BEGIN TRAN/COMMIT su più tabelle e sp_rename.
Cross-database query nello stesso workspace
Warehouse ed endpoint SQL condividono lo stesso motore, quindi puoi fare join diretti con nomi a tre parti, senza copiare dati e senza linked server:
-- Eseguita dal Warehouse: legge dal Lakehouse, scrive nel Warehouse
INSERT INTO dbo.FactSalesEnriched (OrderId, CustomerId, Amount, Region)
SELECT o.OrderId,
o.CustomerId,
o.Amount,
c.Region
FROM SalesLakehouse.dbo.orders_bronze AS o
JOIN dbo.DimCustomer AS c
ON c.CustomerId = o.CustomerId;
La regola operativa: la lettura è bidirezionale, la scrittura solo verso il warehouse. Se ti serve materializzare il risultato di un join, la destinazione deve essere una tabella del warehouse (o del lakehouse, ma tramite Spark/pipeline).
Ritardo di sincronizzazione dei metadati Delta
L’endpoint SQL non legge i file Delta in tempo reale: un processo in background sincronizza i metadati delle tabelle Delta nel catalogo SQL. Conseguenze pratiche:
- Dopo una scrittura Spark, la tabella o le nuove righe possono non essere immediatamente visibili via T-SQL (tipicamente secondi, ma con molte tabelle o scritture frequenti la latenza cresce).
- In una pipeline che fa “Notebook Spark → Stored procedure SQL”, va inserito un passo di refresh dei metadati dell’endpoint (azione di sync nel portale o API REST) prima dello step SQL, altrimenti si legge uno stato stale.
- Tabelle con feature Delta o tipi non supportati (es. tipi complessi/nested, alcune feature del protocol) possono comparire in errore o non comparire affatto: la soluzione è esporre una vista appiattita o riscrivere la tabella in formato compatibile.
- I dati caricati come file (CSV/Parquet non registrati come tabella Delta) non sono visibili all’endpoint: vanno prima convertiti in tabella Delta.
Trappole tipiche d’esame
- Scenario: gli analisti devono eseguire
UPDATEcorrettivi su una dimensione già caricata nel lakehouse, usando solo T-SQL. → Risposta giusta: caricare/spostare la tabella in un Warehouse; l’endpoint SQL del lakehouse è read-only e nessun grant o ruolo lo rende scrivibile. - Scenario: serve incapsulare una logica di reporting sul lakehouse riutilizzabile da Power BI, senza modificare i dati. → Risposta giusta: creare view o stored procedure di sola lettura sull’endpoint SQL (non serve un warehouse aggiuntivo).
- Scenario: una pipeline deve aggiornare due tabelle e garantire che o entrambe riescano o nessuna. → Risposta giusta: transazione esplicita multi-table nel warehouse; l’endpoint e le scritture Spark non offrono transazioni cross-table.
- Scenario: dopo un notebook Spark, la stored procedure a valle non trova le righe nuove. → Risposta giusta: attendere/forzare la sincronizzazione dei metadati Delta dell’endpoint SQL, non ricreare la tabella.
- Scenario: il team chiede di garantire l’unicità di una chiave con un
UNIQUEconstraint nel warehouse. → Risposta giusta: i constraint sono NOT ENFORCED; la deduplica va gestita nella logica di caricamento (es.MERGEo dedup a monte). - Scenario: join fra un warehouse in Workspace A e un lakehouse in Workspace B con nomi a tre parti. → Risposta giusta: non supportato — usare una shortcut OneLake per portare i dati nello stesso workspace.