Utilizzi dei parametri con valori di tabella in ODBC
Si applica a: SQL Server Database SQL di Azure Istanza gestita di SQL di Azure Azure Synapse Analytics Piattaforma di strumenti analitici (PDW)
In questo argomento vengono illustrati gli scenari utente principali relativi all'utilizzo di parametri con valori di tabella in ODBC:
Parametro con valori di tabella con buffer a più righe completamente associati (invio di dati come TVP con tutti i valori in memoria)
Parametro con valori di tabella con flusso di righe (invio di dati come TVP mediante data-at-execution)
Recupero dei metadati del parametro con valori di tabella dal catalogo di sistema
Recupero di metadati del parametro con valori di tabella per un'istruzione preparata
Parametro con valori di tabella con buffer a più righe completamente associati (invio di dati come TVP con tutti i valori in memoria)
Se utilizzato con buffer a più righe completamente associati, tutti i valori del parametro sono disponibili in memoria. È tipico, ad esempio, di una transazione OLTP nella quale i parametri con valori di tabella possono essere assemblati in una singola stored procedure. Senza parametri con valori di tabella, risulta necessario generare dinamicamente un batch complesso con più istruzioni o effettuare più chiamate al server.
Il parametro con valori di tabella stesso è associato tramite SQLBindParameter insieme agli altri parametri. Dopo che tutti i parametri sono stati associati, l'applicazione imposta l'attributo di stato attivo del parametro, SQL_SOPT_SS_PARAM_FOCUS, in ogni parametro con valori di tabella e chiama SQLBindParameter per le colonne del parametro con valori di tabella.
Il tipo di server per un parametro con valori di tabella è un nuovo tipo specifico di SQL Server, SQL_SS_TABLE. Il tipo C dell'associazione per SQL_SS_TABLE deve essere sempre SQL_C_DEFAULT. Non vengono trasferiti dati per il parametro associato al parametro con valori di tabella; viene utilizzato per passare i metadati delle tabelle e per controllare il modo in cui passare i dati nelle colonne che costituiscono il parametro con valori di tabella.
La lunghezza del parametro con valori di tabella è impostata sul numero di righe inviate al server. Il parametro ColumnSize di SQLBindParameter per un parametro con valori di tabella specifica il numero massimo di righe che è possibile inviare. Si tratta della dimensione della matrice dei buffer di colonna. ParameterValuePtr è il buffer dei parametri. Per un parametro con valori di tabella in SQLBindParameter, ParameterValuePtr e il relativo bufferLength associato vengono usati per passare il nome del tipo del parametro con valori di tabella quando necessario. Il nome del tipo non è necessario per le chiamate alle stored procedure, mentre è necessario per le istruzioni SQL.
Quando un nome di tipo di parametro con valori di tabella viene specificato in una chiamata a SQLBindParameter, deve essere sempre specificato come valore Unicode, anche nelle applicazioni compilate come applicazioni ANSI. Quando si specifica un nome di tipo di parametro con valori di tabella tramite SQLSetDescField, è possibile usare un valore letterale conforme alla modalità di compilazione dell'applicazione. In Gestione driver ODBC verrà eseguita la conversione Unicode necessaria.
I metadati per i parametri con valori di tabella e le colonne dei parametri con valori di tabella possono essere modificati singolarmente e in modo esplicito usando SQLGetDescRec, SQLSetDescRec, SQLGetDescField e SQLSetDescField. Tuttavia, l'overload di SQLBindParameter è in genere più pratico e non richiede l'accesso esplicito al descrittore nella maggior parte dei casi. Questo approccio è coerente con la definizione di SQLBindParameter per altri tipi di dati, ad eccezione del fatto che per un parametro con valori di tabella i campi del descrittore interessati sono leggermente diversi.
Un'applicazione utilizza talvolta un parametro con valori di tabella con le istruzioni SQL dinamiche ed è necessario fornire il nome del tipo del parametro con valori di tabella. Se si tratta del caso e il parametro con valori di tabella non è definito nello schema predefinito corrente per la connessione, SQL_CA_SS_SCHEMA_NAME deve essere impostato tramite SQLSetDescField. Poiché le definizioni dei tipi di tabella e i parametri con valori di tabella devono trovarsi nello stesso database, SQL_CA_SS_CATALOG_NAME non deve essere impostata se l'applicazione usa parametri con valori di tabella. In caso contrario, SQLSetDescField segnala un errore.
Il codice di esempio per questo scenario si trova nella procedura demo_fixed_TVP_binding
descritta in Usare parametri con valori di tabella (ODBC).
Parametro con valori di tabella con flusso di righe (invio di dati come TVP mediante data-at-execution)
In questo scenario l'applicazione fornisce le righe al driver nel modo in cui vengono richieste, le quali vengono poi trasferite al server. In questo modo si evita di dovere memorizzare tutte le righe nel buffer di memoria. Tale condizione è rappresentativa negli scenari di inserimento/aggiornamento bulk. Le prestazioni dei parametri con valori di tabella sono a metà tra le matrici di parametri e la copia bulk. La programmazione dei parametri con valori di tabella è semplice quanto quella delle matrici di parametri, ma offre una maggiore flessibilità sul lato server.
Il parametro con valori di tabella e le relative colonne vengono associate come descritto nella sezione precedente, Parametro con valori di tabella con buffer a più righe completamente associati, impostando però l'indicatore della lunghezza del parametro con valori di tabella su SQL_DATA_AT_EXEC. Il driver risponde a SQLExecute o SQLExecuteDirect nel modo consueto per i parametri di data-at-execution, ovvero restituendo SQL_NEED_DATA. Quando il driver è pronto per accettare dati per un parametro con valori di tabella, SQLParamData restituisce il valore di ParameterValuePtr in SQLBindParameter.
Un'applicazione usa SQLPutData per un parametro con valori di tabella per indicare la disponibilità dei dati per le colonne costitutive dei parametri con valori di tabella. Quando SQLPutData viene chiamato per un parametro con valori di tabella, DataPtr deve essere sempre Null e StrLen_or_Ind deve essere 0 o un numero minore o uguale alla dimensione della matrice specificata per i buffer dei parametri con valori di tabella (il parametro ColumnSize di SQLBindParameter). 0 significa che non ci sono più righe per il parametro con valori di tabella e il driver procederà con l'elaborazione fino al successivo parametro effettivo della procedura. Quando StrLen_or_Ind non è 0, il driver elabora le colonne costitutive dei parametri con valori di tabella nello stesso modo dei parametri associati a parametri non con valori di tabella: ogni colonna di parametri con valori di tabella può specificare la lunghezza effettiva dei dati, SQL_NULL_DATA oppure può specificare i dati in fase di esecuzione tramite il buffer di lunghezza/indicatore. I valori delle colonne dei parametri con valori di tabella possono essere passati tramite chiamate ripetute a SQLPutData come di consueto quando un carattere o un valore binario deve essere passato in parti.
Una volta elaborate tutte le colonne del parametro con valori di tabella, il driver torna al parametro con valori di tabella per elaborare ulteriori righe di dati del parametro con valori di tabella. Pertanto, per i parametri con valori di tabella data-at-execution il driver non segue la solita analisi sequenziale dei parametri associati. Verrà eseguito il polling di un parametro associato con valori di tabella fino a quando SQLPutData non viene chiamato con StrLen_Or_IndPtr uguale a 0, quando il driver ignora le colonne dei parametri con valori di tabella e passa al parametro effettivo della stored procedure successivo. Quando SQLPutData passa un valore indicatore maggiore o uguale a 1, il driver elabora in sequenza colonne e righe di parametri con valori di tabella fino a quando non contiene valori per tutte le righe e le colonne associate. Dopodiché il driver torna al parametro con valori di tabella. Tra la ricezione del token per il parametro con valori di tabella da SQLParamData e la chiamata di SQLPutData(hstmt, NULL, n) per un parametro con valori di tabella, l'applicazione deve impostare i dati della colonna costitutiva del parametro con valori di tabella e il contenuto del buffer indicatore per la riga o le righe successive da passare al server.
Il codice di esempio per questo scenario si trova nella routine demo_variable_TVP_binding
in Use Table-Valued Parameters (ODBC).
Recupero dei metadati del parametro con valori di tabella dal catalogo di sistema
Quando un'applicazione chiama SQLProcedureColumns per una routine con parametri di parametro con valori di tabella, DATA_TYPE viene restituito come SQL_SS_TABLE e TYPE_NAME è il nome del tipo di tabella per il parametro con valori di tabella. Al set di risultati restituito da SQLProcedureColumns vengono aggiunte due colonne aggiuntive: SS_TYPE_CATALOG_NAME restituisce il nome del catalogo in cui è definito il tipo di tabella del parametro table-value e SS_TYPE_SCHEMA_NAME restituisce il nome dello schema in cui è definito il tipo di tabella del parametro table-value. In conformità con la specifica ODBC, SS_TYPE_CATALOG_NAME e SS_TYPE_SCHEMA_NAME vengono visualizzate prima di tutte le colonne specifiche del driver aggiunte nelle versioni precedenti di SQL Server e dopo tutte le colonne richieste da ODBC stesso.
Le nuove colonne verranno popolate non solo per i parametri con valori di tabella, ma anche per i parametri del tipo CLR definito dall'utente. Le colonne esistenti dello schema e del catalogo dei parametri UDT verranno ancora popolate, ma la disponibilità di colonne comuni per lo schema e il catalogo da utilizzare per i tipi di dati semplificherà in futuro lo sviluppo di applicazioni. Notare che le raccolte di XML Schema sono piuttosto diverse e non sono incluse in questa modifica.
Un'applicazione usa tabelle SQLTable per determinare i nomi dei tipi di tabella nello stesso modo in cui viene usata per tabelle persistenti, tabelle di sistema e viste. Viene introdotto un nuovo tipo di tabella, TABLE TYPE, per consentire a un'applicazione di identificare i tipi di tabella associati ai parametri con valori di tabella. I tipi di tabella e le tabelle normali utilizzano spazi dei nomi diversi. È pertanto possibile utilizzare lo stesso nome per un tipo di tabella e una tabella effettiva. A tale scopo è stato introdotto un nuovo attributo dell'istruzione, SQL_SOPT_SS_NAME_SCOPE. Questo attributo specifica se SQLTables e altre funzioni del catalogo che accettano un nome di tabella come parametro devono interpretare il nome della tabella come nome di una tabella effettiva o il nome di un tipo di tabella.
Un'applicazione usa SQLColumns per determinare le colonne per un tipo di tabella nello stesso modo in cui viene eseguita per le tabelle persistenti, ma deve prima impostare SQL_SOPT_SS_NAME_SCOPE per indicare che funziona con i tipi di tabella anziché con le tabelle effettive. È anche possibile usare SQLPrimaryKeys con i tipi di tabella, usando di nuovo SQL_SOPT_SS_NAME_SCOPE.
Il codice di esempio per questo scenario si trova nella routine demo_metadata_from_catalog_APIs
in Use Table-Valued Parameters (ODBC).
Recupero di metadati del parametro con valori di tabella per un'istruzione preparata
In questo scenario, un'applicazione usa SQLNumParameters e SQLDescribeParam per recuperare i metadati per i parametri con valori di tabella.
Il campo IPD SQL_CA_SS_TYPE_NAME viene utilizzato per recuperare il nome del tipo per il parametro con valori di tabella. I campi IPD SQL_CA_SS_SCHEMA_NAME e SQL_CA_SS_CATALOG_NAME vengono usati rispettivamente per recuperare il catalogo e lo schema.
Le definizioni del tipo di tabella e i parametri con valori di tabella devono essere nello stesso database. SQLSetDescField segnala un errore se un'applicazione imposta SQL_CA_SS_CATALOG_NAME quando si usano parametri con valori di tabella.
SQL_CA_SS_CATALOG_NAME e SQL_CA_SS_SCHEMA_NAME possono essere usati anche per recuperare il catalogo e lo schema associati ai parametri di tipo CLR definiti dall'utente. SQL_CA_SS_CATALOG_NAME e SQL_CA_SS_SCHEMA_NAME sono alternative agli attributi dello schema del catalogo specifici del tipo esistenti per i tipi CLR UDT.
Un'applicazione usa SQLColumns per recuperare i metadati di colonna per un parametro con valori di tabella in questo scenario, anche perché SQLDescribeParam non restituisce metadati per le colonne di una colonna di parametri con valori di tabella.
Il codice di esempio per questo caso d'uso è nella routine demo_metadata_from_prepared_statement
in Usare parametri con valori di tabella (ODBC).