Associazione e trasferimento dati di valori di colonna e parametri con valori di tabella

Si applica a: SQL Server Azure SQL DatabaseIstanza gestita di SQL di AzureAzure Synapse Analytics AnalyticsPlatform System (PDW)

I parametri con valori di tabella (TVP), come altri parametri, devono essere associati prima che vengano passati al server. L'applicazione associa parametri con valori di tabella allo stesso modo in cui associa altri parametri: usando SQLBindParameter o chiamate equivalenti a SQLSetDescField o SQLSetDescRec. Il tipo di dati del server per un parametro con valori di tabella è SQL_SS_TABLE. Il tipo C può essere specificato come SQL_C_DEFAULT o SQL_C_BINARY.

In SQL Server 2008 (10.0.x) o versioni successive sono supportati solo i parametri con valori di tabella di input. Pertanto, qualsiasi tentativo di impostare SQL_DESC_PARAMETER_TYPE su un valore diverso da SQL_PARAM_INPUT restituisce SQL_ERROR con SQLSTATE = HY105 e il messaggio "Tipo di parametro non valido".

È possibile assegnare valori predefiniti a intere colonne dei parametri con valori di tabella utilizzando l'attributo SQL_CA_SS_COL_HAS_DEFAULT_VALUE. Ai singoli valori di colonna dei parametri con valori di tabella, tuttavia, non è possibile assegnare valori predefiniti usando SQL_DEFAULT_PARAM in StrLen_or_IndPtr con SQLBindParameter. I parametri con valori di tabella nel suo complesso non possono essere impostati su un valore predefinito usando SQL_DEFAULT_PARAM in StrLen_or_IndPtr con SQLBindParameter. Se queste regole non sono seguite, SQLExecute o SQLExecDirect restituisce SQL_ERROR. Viene generato un record di diagnostica con SQLSTATE=07S01 e il messaggio "Uso non valido del parametro predefinito per il parametro <p>", dove <p> è l'ordinale del file TVP nell'istruzione di query.

Nota

I parametri con valori di tabella non hanno un valore predefinito che può essere impostato, perché SQL_DEFAULT_PARAM indica che non sono presenti righe. Pertanto, se non sono presenti righe, non sono presenti colonne da associare.

Dopo avere associato il parametro con valori di tabella, dovrà essere associata anche ogni colonna del parametro. A tale scopo, l'applicazione chiama prima SQLSetStmtAttr per impostare SQL_SOPT_SS_PARAM_FOCUS sul numero ordinale di un parametro con valori di tabella. L'applicazione associa le colonne del parametro con valori di tabella tramite chiamate alle routine seguenti: SQLBindParameter, SQLSetDescRec e SQLSetDescField. L'impostazione di SQL_SOPT_SS_PARAM_FOCUS su 0 ripristina l'effetto consueto di SQLBindParameter, SQLSetDescRec e SQLSetDescField in funzionamento su normali parametri di primo livello.

Nota

Per i driver ODBC Linux e Mac con unixODBC 2.3.1 a 2.3.4, quando si imposta il nome TVP tramite SQLSetDescField con il campo del descrittore SQL_CA_SS_TYPE_NAME, unixODBC non converte automaticamente tra stringhe ANSI e Unicode a seconda della funzione esatta chiamata (SQLSetDescFieldA /SQLSetDescFieldW). È necessario usare sempre SQLBindParameter o SQLSetDescFieldW con una stringa Unicode (UTF-16) per impostare il nome TVP.

La ricezione e l'invio di dati effettivi non riguardano il parametro con valori di tabella stesso ma ognuna delle colonne che lo costituiscono. Poiché il parametro con valori di tabella è una pseudo colonna, i parametri per SQLBindParameter fanno riferimento a attributi diversi rispetto ad altri tipi di dati, come indicato di seguito:

Parametro Attributo correlato per i tipi di parametro non con valori di tabella, incluse le colonne Attributo correlato per i parametri con valori di tabella
InputOutputType SQL_DESC_PARAMETER_TYPE in IPD.

Per le colonne dei parametri con valori di tabella, deve corrispondere all'impostazione per il parametro con valori di tabella stesso.
SQL_DESC_PARAMETER_TYPE in IPD.

Deve essere SQL_PARAM_INPUT.
ValueType SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE in APD. SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE in APD.

Deve essere SQL_C_DEFAULT o SQL_C_BINARY.
Parametertype SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE in IPD. SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE in IPD.

Deve essere SQL_SS_TABLE.
ColumnSize SQL_DESC_LENGTH o SQL_DESC_PRECISION in IPD.

Dipende dal valore di ParameterType.
SQL_DESC_ARRAY_SIZE

Può essere impostato anche utilizzando SQL_ATTR_PARAM_SET_SIZE quando lo stato attivo del parametro è impostato sul parametro con valori di tabella.

Per un parametro con valori di tabella, è il numero di righe nei buffer delle colonne dei parametri con valori di tabella.
DecimalDigits SQL_DESC_PRECISION o SQL_DESC_SCALE in IPD. Non utilizzato. Deve essere 0.

Se questo parametro non è 0, SQLBindParameter restituisce SQL_ERROR e viene generato un record di diagnostica con SQLSTATE= HY104 e il messaggio "Precisione o scala non valida".
ParameterValuePtr SQL_DESC_DATA_PTR in APD. SQL_CA_SS_TYPE_NAME.

Questa opzione è facoltativa per le chiamate di stored procedure e è possibile specificare NULL se non è necessaria. Deve essere specificato per le istruzioni SQL che non sono chiamate di routine.

Questo parametro serve anche come valore univoco utilizzabile dall'applicazione per identificare il parametro con valori di tabella quando viene utilizzata l'associazione variabile di righe. Per ulteriori informazioni, vedere la sezione "Associazione variabile di righe di parametri con valori di tabella" più avanti n questo argomento.

Quando un nome di tipo di parametro con valori di tabella viene specificato in una chiamata a SQLBindParameter, deve essere specificato come valore Unicode, anche nelle applicazioni compilate come applicazioni ANSI. Il valore utilizzato per il parametro StrLen_or_IndPtr deve essere SQL_NTS o la lunghezza della stringa del nome moltiplicato per dimensione (WCHAR).
BufferLength SQL_DESC_OCTET_LENGTH in APD. Lunghezza del nome del tipo di parametro con valori di tabella espressa in byte.

Può essere SQL_NTS se il nome del tipo è con terminazione Null o 0 se il nome del tipo di parametro con valori di tabella non è obbligatorio.
StrLen_or_IndPtr SQL_DESC_OCTET_LENGTH_PTR in APD. SQL_DESC_OCTET_LENGTH_PTR in APD.

Per i parametri con valori di tabella è un conteggio di righe anziché una lunghezza di dati.

Sono supportate due modalità di trasferimento dati per i parametri con valori di tabella: associazione di righe fissa e variabile.

Associazione fissa di righe di parametri con valori di tabella

Per l'associazione fissa di righe, un'applicazione alloca i buffer (o le matrici di buffer) di dimensioni sufficienti a contenere tutti i possibili valori delle colonne di input. L'applicazione effettua quanto segue:

  1. Associa tutti i parametri tramite chiamate SQLBindParameter, SQLSetDescRec o SQLSetDescField.

    1. Imposta SQL_DESC_ARRAY_SIZE sul numero massimo di righe che possono essere trasferite per ogni parametro con valori di tabella. Questa operazione può essere eseguita nella chiamata a SQLBindParameter.
  2. Chiama SQLSetStmtAttr per impostare SQL_SOPT_SS_PARAM_FOCUS sul numero ordinale di ogni parametro con valori di tabella.

    1. Per ogni parametro con valori di tabella, associa le colonne dei parametri con valori di tabella tramite chiamate SQLBindParameter, SQLSetDescRec o SQLSetDescField.

    2. Per ogni colonna di parametri con valori di tabella con valori predefiniti, chiama SQLSetDescField per impostare SQL_CA_SS_COL_HAS_DEFAULT_VALUE su 1.

  3. Chiama SQLSetStmtAttr per impostare SQL_SOPT_SS_PARAM_FOCUS su 0. Questa operazione deve essere eseguita prima di chiamare SQLExecute o SQLExecDirect. In caso contrario, viene restituito SQL_ERROR e viene generato un record di diagnostica con SQLSTATE=HY024 e il messaggio "Valore attributo non valido, SQL_SOPT_SS_PARAM_FOCUS (deve essere zero in fase di esecuzione)."

  4. Imposta StrLen_or_IndPtr o SQL_DESC_OCTET_LENGTH_PTR su SQL_DEFAULT_PARAM per un parametro con valori di tabella senza righe o sul numero di righe da trasferire alla chiamata successiva di SQLExecute o SQLExecDirect se il parametro con valori di tabella contiene righe. StrLen_or_IndPtr o SQL_DESC_OCTET_LENGTH_PTR non possono essere impostati su SQL_NULL_DATA per un parametro con valori di tabella come parametri con valori di tabella non sono nullable (anche se le colonne costitutive dei parametri con valori di tabella possono essere nullable). Se questo valore è impostato su un valore non valido, SQLExecute o SQLExecDirect restituisce SQL_ERROR e viene generato un record di diagnostica con SQLSTATE=HY090 e il messaggio "Stringa o lunghezza buffer non valida per il parametro <p>", dove p è il numero di parametro.

  5. Chiama SQLExecute o SQLExecDirect.

    I valori delle colonne dei parametri con valori di tabella di input possono essere passati in parti se StrLen_or_IndPtr è impostato su SQL_LEN_DATA_AT_EXEC(lunghezza) o SQL_DATA_AT_EXEC per la colonna. Si tratta di una procedura analoga a quella utilizzata per passare i valori in parti quando vengono utilizzate matrici di parametri. Come per tutti i parametri di esecuzione dei dati, SQLParamData non indica per quale riga della matrice il driver richiede dati; l'applicazione deve occuparsi di questo. L'applicazione non può fare ipotesi sull'ordine in cui il driver richiede valori.

Associazione variabile di righe di parametri con valori di tabella

Per l'associazione di righe variabili, le righe vengono trasferite in batch in fase di esecuzione e l'applicazione passa righe al driver su richiesta. Si tratta di una procedura simile al data-at-execution per i valori di parametri singoli. Per l'associazione variabile di righe, l'applicazione effettua quanto segue:

  1. Associa parametri e colonne di parametri con valori di tabella, come descritto nei passaggi da 1 a 3 della sezione precedente, "Fixed Table-Valued Parameter Row Binding".

  2. Imposta StrLen_or_IndPtr o SQL_DESC_OCTET_LENGTH_PTR per i parametri con valori di tabella da passare in fase di esecuzione a SQL_DATA_AT_EXEC. Se nessuno dei due è impostato, il parametro viene elaborato come descritto nella sezione precedente.

  3. Chiama SQLExecute o SQLExecDirect. Questo restituisce SQL_NEED_DATA se sono presenti parametri SQL_PARAM_INPUT o SQL_PARAM_INPUT_OUTPUT da gestire come parametri di esecuzione in fase di esecuzione dei dati. In questo caso, l'applicazione effettua quanto segue:

    • Chiama SQLParamData. Questo restituisce il valore ParameterValuePtr per un parametro di esecuzione in fase di dati e un codice restituito di SQL_NEED_DATA. Quando tutti i dati dei parametri sono stati passati al driver, SQLParamData restituisce SQL_SUCCESS, SQL_SUCCESS_WITH_INFO o SQL_ERROR. Per i parametri di esecuzione in fase di dati, ParameterValuePtr, che corrisponde al campo descrittore SQL_DESC_DATA_PTR, può essere considerato un token per identificare un parametro per il quale è necessario un valore univoco. Tale "token" viene passato dall'applicazione al driver in fase di associazione, quindi viene passato nuovamente all'applicazione in fase di esecuzione.
  4. Per inviare dati di riga dei parametri con valori di tabella null per i parametri con valori di tabella Null, se il parametro con valori di tabella non ha righe, un'applicazione chiama SQLPutData con StrLen_or_Ind impostata su SQL_DEFAULT_PARAM .

    Per i TVP non Null, un'applicazione:

    • Imposta Str_Len_or_Ind per tutte le colonne dei parametri con valori di tabella ai valori appropriati e popola i buffer di dati per le colonne dei parametri con valori di tabella che non sono parametri di esecuzione in fase di dati. È possibile utilizzare la funzionalità data-at-execution per le colonne di parametri con valori di tabella seguendo procedure analoghe a quelle necessarie per passare in parti i parametri ordinari al driver.

    • Chiama SQLPutData con Str_Len_or_Ind impostato sul numero di righe da inviare al server. Qualsiasi valore all'esterno dell'intervallo da 0 a SQL_DESC_ARRAY_SIZE o SQL_DEFAULT_PARAM è un errore e restituisce SQLSTATE HY090, con il messaggio "Lunghezza stringa o buffer non valida". 0 indica che tutte le righe sono state inviate e non sono presenti più dati per un parametro con valori di tabella (come indicato nel secondo elemento elenco in questo elenco). SQL_DEFAULT_PARAM può essere utilizzato solo la prima volta che il driver richiede dati per un parametro con valori di tabella (come descritto nel primo punto elenco).

  5. Quando tutte le righe sono state inviate, chiama SQLPutData per il parametro con valori di tabella con un valore di Str_Len_or_Ind 0, quindi procedere al passaggio 3a precedente.

  6. Chiama di nuovo SQLParamData. Se sono presenti parametri data-at-execution tra le colonne dei parametri con valori di tabella, questi sono identificati dal valore ValuePtrPtrPtr restituito da SQLParamData. Quando sono disponibili tutti i valori di colonna, SQLParamData restituisce il valore ParameterValuePtr per il parametro con valori di tabella e l'applicazione inizia di nuovo.

Passaggi successivi

Parametri con valori di tabella ODBC