Associazione e trasferimento dati di valori di colonna e parametri con valori di tabella
Analogamente agli altri parametri, i parametri con valori di tabella devono essere associati prima di poter essere passati al server. Le modalità con cui i parametri con valori di tabella vengono associati sono uguali a quelle per l'associazione di altri parametri, ovvero mediante SQLBindParameter o chiamate equivalenti a SQLSetDescField o a 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 sono supportati solo parametri con valori di tabella di input. Qualsiasi tentativo di impostare SQL_DESC_PARAMETER_TYPE su un valore diverso da SQL_PARAM_INPUT restituirà, pertanto, 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. Non è invece possibile assegnare valori predefiniti ai singoli valori delle colonne dei parametri con valori di tabella utilizzando l'attributo SQL_DEFAULT_PARAM in StrLen_or_IndPtr con SQLBindParameter. I parametri con valori di tabella nel complesso non possono essere impostati su un valore predefinito utilizzando SQL_DEFAULT_PARAM in StrLen_or_IndPtr con SQLBindParameter. Se non vengono rispettate queste regole, SQLExecute o SQLExecDirect restituirà SQL_ERROR. Verrà generato un record di dati diagnostici con SQLSTATE=07S01 e verrà visualizzato il messaggio "Utilizzo del parametro predefinito non valido per il parametro <p>", dove <p> è il numero ordinale del parametro con valori di tabella (TVP, Table-Valued Parameter) nell'istruzione di query.
Dopo avere associato il parametro con valori di tabella, dovrà essere associata anche ogni colonna del parametro. A questo scopo, viene chiamato SQLSetStmtAttr per impostare SQL_SOPT_SS_PARAM_FOCUS sul numero ordinale di un parametro con valori di tabella. Le colonne del parametro con valori di tabella vengono quindi associate mediante chiamate alle routine seguenti: SQLBindParameter, SQLSetDescRec e SQLSetDescField. L'impostazione di SQL_SOPT_SS_PARAM_FOCUS su 0 ripristina l'effetto tipico di SQLBindParameter, SQLSetDescRec e SQLSetDescField, ovvero la sua azione sui regolari parametri di livello superiore.
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 pseudocolonna, per fare riferimento ad attributi diversi dagli altri tipi di dati, vengono utilizzati i parametri per SQLBindParameter, 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 restituirà SQL_ERROR e verranno generati un record di dati diagnostici con SQLSTATE = HY104 e il messaggio "Precisione o valore di scala non valido". |
ParameterValuePtr |
SQL_DESC_DATA_PTR in APD. |
SQL_CA_SS_TYPE_NAME. Questo parametro è facoltativo per le chiamate di stored procedure ed è possibile specificare NULL se non è richiesto. Deve essere specificato per le istruzioni SQL che non sono chiamate di stored procedure. 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 viene specificato in una chiamata a SQLBindParameter, un nome di tipo di parametro con valori di tabella deve essere specificato come valore Unicode, anche in applicazioni generate come applicazioni ANSI. Il valore utilizzato per il parametro StrLen_or_IndPtr deve essere SQL_NTS oppure la lunghezza della stringa del nome moltiplicata per sizeof(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 oppure 0 se il nome del tipo di parametro con valori di tabella non è richiesto. |
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:
Associa tutti i parametri mediante chiamate SQLBindParameter, SQLSetDescRec o SQLSetDescField.
- 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.
Chiama SQLSetStmtAttr per impostare SQL_SOPT_SS_PARAM_FOCUS sul numero ordinale per ogni parametro con valori di tabella.
Per ogni parametro con valori di tabella, associa le colonne dei parametri con valori di tabella mediante chiamate SQLBindParameter, SQLSetDescRec o SQLSetDescField.
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.
Chiama SQLSetStmtAttr per impostare SQL_SOPT_SS_PARAM_FOCUS su 0. Questa operazione deve essere eseguita prima che venga chiamato SQLExecute o SQLExecDirect. In caso contrario, viene restituito SQL_ERROR e vengono generati un record di dati diagnostici con SQLSTATE=HY024 e il messaggio "Valore attributo non valido, SQL_SOPT_SS_PARAM_FOCUS (deve essere zero in fase di esecuzione)."
Imposta StrLen_or_IndPtr o SQL_DESC_OCTET_LENGTH_PTR su SQL_DEFAULT_PARAM per un parametro con valori di tabella senza righe o il numero di righe da trasferire nella chiamata successiva di SQLExecute o SQLExecDirect, se nel parametro con valori di tabella sono presenti righe. Non è possibile impostare StrLen_or_IndPtr o SQL_DESC_OCTET_LENGTH_PTR su SQL_NULL_DATA per un parametro con valori di tabella, in quanto i parametri con valori di tabella non ammettono valori Null (anche se le colonne che costituiscono il parametro con valori di tabella potrebbero ammettere valori Null). Se è impostato su un valore non valido, SQLExecute o SQLExecDirect restituisce SQL_ERROR e vengono generati un record di dati diagnostici con SQLSTATE=HY090 e il messaggio "Lunghezza di stringa o di buffer non valida per il parametro <p>.", dove p è il numero del parametro.
Chiama SQLExecute o SQLExecDirect.
I valori della colonna di parametri con valori di tabella di input possono essere passati in parti se StrLen_or_IndPtr è impostato su SQL_LEN_DATA_AT_EXEC (length) 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 data-at-execution, SQLParamData non indica per quale riga della matrice il driver richiede dati. Questa operazione dovrà essere eseguita dall'applicazione. L'applicazione non può prevedere l'ordine con il quale il driver richiederà i valori.
Associazione variabile di righe di parametri con valori di tabella
Per l'associazione variabile di righe, 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:
Associa i parametri e le colonne di parametri con valori di tabella come descritto nei passaggi da 1 a 3 della sezione precedente, "Associazione fissa di righe di parametri con valori di tabella".
Imposta StrLen_or_IndPtr o SQL_DESC_OCTET_LENGTH_PTR per qualsiasi parametro con valori di tabella che deve essere passato in fase di esecuzione a SQL_DATA_AT_EXEC. Se non sono impostati valori, il parametro verrà elaborato come descritto nella sezione precedente.
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 data-at-execution. In questo caso, l'applicazione effettua quanto segue:
- Chiama SQLParamData. Restituisce 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 data-at-execution, ParameterValuePtr, che corrisponde al campo di descrizione SQL_DESC_DATA_PTR, può essere considerato come token per identificare in modo univoco un parametro per il quale viene richiesto un valore. Tale "token" viene passato dall'applicazione al driver in fase di associazione, quindi viene passato nuovamente all'applicazione in fase di esecuzione.
Per inviare dati delle righe di parametri con valori di tabella per i parametri con valori di tabella null, se per il parametro con valori di tabella non sono presenti 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 di 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 devono essere parametri data-at-execution. È 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. I valori esterni all'intervallo compreso tra 0 e SQL_DESC_ARRAY_SIZE o SQL_DEFAULT_PARAM sono un errore e restituiranno SQLSTATE HY090, con il messaggio "Lunghezza di stringa o di buffer non valida". 0 indica che tutte le righe sono state inviate e non sono più disponibili dati per un parametro con valori di tabella (come indicato nel secondo punto 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).
Quando tutte le righe sono state inviate, chiama SQLPutData per il parametro con valori di tabella con un valore 0 per Str_Len_or_Ind, quindi procede con il passaggio 3a.
Chiama nuovamente SQLParamData. Se tra le colonne di parametri con valori di tabella sono presenti parametri data-at-execution, questi verranno identificati dal valore ValuePtrPtr restituito da SQLParamData. Quando tutti i valori di colonna sono disponibili, SQLParamData restituirà nuovamente il valore ParameterValuePtr per il parametro con valori di tabella e l'applicazione verrà nuovamente avviata.