Condividi tramite


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

Si applica a: SQL Server database SQL di Azure Istanza gestita di SQL di Azure azure Synapse Analytics Analytics Platform System (PDW)

I parametri con valori di tabella (TVP), come gli 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 vengono 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 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 sull'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 modo da operare su parametri di primo livello regolari.

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 esegue automaticamente la conversione 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 parametri 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.

Questo 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 usato 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 usando 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 sull'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 oppure il 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 è 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 del 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 le 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 i parametri e le colonne dei 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. Verrà restituito SQL_NEED_DATA se sono presenti parametri SQL_PARAM_INPUT o SQL_PARAM_INPUT_OUTPUT da gestire come parametri di esecuzione dei dati. In questo caso, l'applicazione effettua quanto segue:

    • Chiama SQLParamData. Viene restituito il valore ParameterValuePtr per un parametro data-at-execution 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 data-at-execution, 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 in modo 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 di parametri con valori di tabella per i parametri con valori di tabella Null, se il parametro con valori di tabella non contiene righe, un'applicazione chiama SQLPutData con StrLen_or_Ind impostato 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 sui valori appropriati e popola i buffer di dati per le colonne di parametri con valori di tabella che non sono parametri di esecuzione dei 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 al di fuori dell'intervallo da 0 a SQL_DESC_ARRAY_SIZE o SQL_DEFAULT_PARAM è un errore e restituisce SQLSTATE HY090, con il messaggio "Stringa o lunghezza del buffer non valida". 0 indica che tutte le righe sono state inviate e che non sono presenti altri dati per un parametro con valori di tabella (come indicato nel secondo punto 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 pari a 0, quindi procedere con il passaggio 3a precedente.

  6. Chiama di nuovo SQLParamData. Se sono presenti parametri di data-at-execution tra le colonne dei parametri con valori di tabella, questi vengono identificati dal valore ValuePtrPtr 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 nuovamente.

Passaggi successivi

Parametri con valori di tabella ODBC