Liaison et transfert de données de paramètres table et de valeurs de colonnes

S’applique à : SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW)

Les paramètres table (TVP), comme d’autres paramètres, doivent être liés avant qu’ils ne soient passés au serveur. L’application lie les paramètres table de la même façon qu’elle lie d’autres paramètres : à l’aide de SQLBindParameter ou d’appels équivalents à SQLSetDescField ou SQLSetDescRec. Le type de données serveur pour un paramètre table est SQL_SS_TABLE. Le type C peut être spécifié comme SQL_C_DEFAULT ou SQL_C_BINARY.

Dans SQL Server 2008 (10.0.x) ou version ultérieure, seuls les paramètres table d’entrée sont pris en charge. Par conséquent, toute tentative de définition de SQL_DESC_PARAMETER_TYPE sur une valeur autre que SQL_PARAM_INPUT retourne SQL_ERROR avec SQLSTATE = HY105 et le message « Type de paramètre non valide ».

Des valeurs par défaut peuvent être assignées à des colonnes de paramètres table entières à l'aide de l'attribut SQL_CA_SS_COL_HAS_DEFAULT_VALUE. Toutefois, les valeurs de colonne de paramètre table individuelles ne peuvent pas être affectées par défaut à l’aide de SQL_DEFAULT_PARAM dans StrLen_or_IndPtr avec SQLBindParameter. Les paramètres table dans son ensemble ne peuvent pas être définis sur une valeur par défaut à l’aide de SQL_DEFAULT_PARAM dans StrLen_or_IndPtr avec SQLBindParameter. Si ces règles ne sont pas suivies, SQLExecute ou SQLExecDirect retourne SQL_ERROR. Un enregistrement de diagnostic est généré avec SQLSTATE=07S01 et le message « Utilisation non valide du paramètre par défaut pour le paramètre <p> », où <p> est l’ordinal du FOURNISSEUR de données dans l’instruction de requête.

Remarque

Les paramètres table n’ont pas de valeur par défaut qui peut être définie, car SQL_DEFAULT_PARAM indique aucune ligne. Par conséquent, s’il n’y a pas de lignes, il n’y a pas de colonnes à lier.

Après avoir lié le paramètre table, l'application doit lier chaque colonne de paramètre table. Pour ce faire, l’application appelle d’abord SQLSetStmtAttr pour définir SQL_SOPT_SS_PARAM_FOCUS sur l’ordinal d’un paramètre table. L’application lie les colonnes du paramètre table en appelant les routines suivantes : SQLBindParameter, SQLSetDescRec et SQLSetDescField. La définition de SQL_SOPT_SS_PARAM_FOCUS sur 0 restaure l’effet habituel de SQLBindParameter, SQLSetDescRec et SQLSetDescField dans le fonctionnement sur des paramètres de niveau supérieur réguliers.

Remarque

Pour les pilotes ODBC Linux et Mac avec unixODBC 2.3.1 à 2.3.4, lors de la définition du nom TVP via SQLSetDescField avec le champ de descripteur SQL_CA_SS_TYPE_NAME, unixBC ne convertit pas automatiquement entre les chaînes ANSI et Unicode en fonction de la fonction exacte appelée (SQLSetDescFieldA / SQLSetDescFieldW). Il est nécessaire d’utiliser toujours SQLBindParameter ou SQLSetDescFieldW avec une chaîne Unicode (UTF-16) pour définir le nom TVP.

Aucune donnée n'est réellement envoyée ou reçue pour le paramètre table lui-même, mais des données sont envoyées et reçues pour chacune de ses colonnes constituantes. Étant donné que le paramètre table est une pseudo-colonne, les paramètres de SQLBindParameter font référence à différents attributs que d’autres types de données, comme suit :

Paramètre Attribut associé pour les types de paramètres non table, y compris les colonnes Attribut associé pour les paramètres table
InputOutputType SQL_DESC_PARAMETER_TYPE dans IPD.

Pour les colonnes de paramètre table, ce doit être identique au paramètre du paramètre table lui-même.
SQL_DESC_PARAMETER_TYPE dans IPD.

Ce doit être SQL_PARAM_INPUT.
ValueType SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE dans APD. SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE dans APD.

Ce doit être SQL_C_DEFAULT ou SQL_C_BINARY.
ParameterType SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE dans IPD. SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE dans IPD.

Ce doit être SQL_SS_TABLE.
ColumnSize SQL_DESC_LENGTH ou SQL_DESC_PRECISION dans IPD.

Cela dépend de la valeur de ParameterType.
SQL_DESC_ARRAY_SIZE

Peut également être défini à l'aide de SQL_ATTR_PARAM_SET_SIZE lorsque le focus de paramètre est défini sur le paramètre table.

Pour un paramètre table, il s'agit du nombre de lignes dans les mémoires tampons de colonnes de paramètres table.
DecimalDigits SQL_DESC_PRECISION or SQL_DESC_SCALE dans IPD. Inutilisé. Doit être 0.

Si ce paramètre n’est pas 0, SQLBindParameter retourne SQL_ERROR et un enregistrement de diagnostic est généré avec SQLSTATE= HY104 et le message « Précision ou échelle non valides ».
ParameterValuePtr SQL_DESC_DATA_PTR dans APD. SQL_CA_SS_TYPE_NAME.

Cela est facultatif pour les appels de procédure stockée, et NULL peut être spécifié s’il n’est pas obligatoire. Il doit être spécifié pour les instructions SQL qui ne sont pas des appels de procédure.

Ce paramètre sert également de valeur unique que l'application peut utiliser pour identifier ce paramètre table lorsque la liaison de ligne variable est utilisée. Pour plus d'informations, consultez la section « Liaison de ligne de paramètre table variable » plus loin dans cette rubrique.

Lorsqu’un nom de type de paramètre table est spécifié sur un appel à SQLBindParameter, il doit être spécifié en tant que valeur Unicode, même dans les applications créées en tant qu’applications ANSI. La valeur utilisée pour le paramètre StrLen_or_IndPtr doit être SQL_NTS ou la longueur de chaîne du nom multipliée par la taille de (WCHAR).
BufferLength SQL_DESC_OCTET_LENGTH dans APD. Longueur du nom de type de paramètre table en octets.

Cela peut être SQL_NTS si le nom de type est terminé par null ou 0 si le nom du type de paramètre table n’est pas obligatoire.
StrLen_or_IndPtr SQL_DESC_OCTET_LENGTH_PTR dans APD. SQL_DESC_OCTET_LENGTH_PTR dans APD.

Pour les paramètres table, il s'agit d'un nombre de lignes plutôt qu'une longueur de données.

Deux modes de transfert de données sont pris en charge pour les paramètres table : la liaison de ligne fixe et la liaison de ligne variable.

Liaison de ligne de paramètre table fixe

Pour la liaison de ligne fixe, une application alloue des mémoires tampon (ou tableaux de mémoires tampon) suffisamment grandes pour toutes les valeurs de colonne d'entrée possibles. L'application effectue les actions suivantes :

  1. Lie tous les paramètres à l’aide des appels SQLBindParameter, SQLSetDescRec ou SQLSetDescField.

    1. Elle définit SQL_DESC_ARRAY_SIZE au nombre maximal de lignes qui peuvent être transférées pour chaque paramètre table. Cette opération peut être effectuée dans l’appel SQLBindParameter.
  2. Appelle SQLSetStmtAttr pour définir SQL_SOPT_SS_PARAM_FOCUS sur l’ordinal de chaque paramètre table.

    1. Pour chaque paramètre table, lie des colonnes de paramètres table à l’aide des appels SQLBindParameter, SQLSetDescRec ou SQLSetDescField.

    2. Pour chaque colonne de paramètre table qui doit avoir des valeurs par défaut, appelle SQLSetDescField pour définir SQL_CA_SS_COL_HAS_DEFAULT_VALUE sur 1.

  3. Appelle SQLSetStmtAttr pour définir SQL_SOPT_SS_PARAM_FOCUS sur 0. Cette opération doit être effectuée avant que SQLExecute ou SQLExecDirect soit appelé. Sinon, SQL_ERROR est retourné et un enregistrement de diagnostic est généré avec SQLSTATE=HY024 et le message « Valeur d’attribut non valide, SQL_SOPT_SS_PARAM_FOCUS (doit être égal à zéro au moment de l’exécution). »

  4. Définit StrLen_or_IndPtr ou SQL_DESC_OCTET_LENGTH_PTR à SQL_DEFAULT_PARAM pour un paramètre table sans ligne, ou le nombre de lignes à transférer lors de l’appel suivant de SQLExecute ou DE SQLExecDirect si le paramètre table comporte des lignes. StrLen_or_IndPtr ou SQL_DESC_OCTET_LENGTH_PTR ne peut pas être défini sur SQL_NULL_DATA pour un paramètre table en tant que paramètres table ne peuvent pas être nullables (bien que les colonnes constituantes de paramètres table puissent être nullables). S’il s’agit d’une valeur non valide, SQLExecute ou SQLExecDirect retourne SQL_ERROR, et un enregistrement de diagnostic est généré avec SQLSTATE=HY090 et le message « Chaîne ou longueur de mémoire tampon non valide pour le paramètre <p> », où p est le numéro de paramètre.

  5. Appelle SQLExecute ou SQLExecDirect.

    Les valeurs de colonne de paramètre table d’entrée peuvent être transmises en morceaux si StrLen_or_IndPtr a la valeur SQL_LEN_DATA_AT_EXEC(length) ou SQL_DATA_AT_EXEC pour la colonne. Cela s'apparente au passage de valeurs en fragments lorsque des tableaux de paramètres sont utilisés. Comme pour tous les paramètres de données au niveau de l’exécution, SQLParamData n’indique pas la ligne du tableau pour lequel le pilote demande des données ; l’application doit s’occuper de cela. L’application ne peut pas faire d’hypothèses sur l’ordre dans lequel le pilote demande des valeurs.

Liaison de ligne de paramètre table variable

Pour la liaison de ligne variable, les lignes sont transférées par lots au moment de l’exécution, et l’application transmet des lignes au pilote à la demande. Cela s'apparente à la fonctionnalité « data-at-execution » pour les valeurs de paramètre individuelles. Pour la liaison de ligne variable, l'application effectue les opérations suivantes :

  1. Lie les paramètres et les colonnes de paramètres table, comme décrit dans les étapes 1 à 3 de la section précédente, « Liaison de ligne de paramètre table fixe ».

  2. Définit StrLen_or_IndPtr ou SQL_DESC_OCTET_LENGTH_PTR pour les paramètres table à passer au moment de l’exécution à SQL_DATA_AT_EXEC. Si aucun n’est défini, le paramètre est traité comme décrit dans la section précédente.

  3. Appelle SQLExecute ou SQLExecDirect. Cela retourne SQL_NEED_DATA s’il existe des paramètres SQL_PARAM_INPUT ou SQL_PARAM_INPUT_OUTPUT à gérer en tant que paramètres de données au niveau de l’exécution. Dans ce cas, l'application effectue les opérations suivantes :

    • Appelle SQLParamData. Cette opération renvoie la valeur ParameterValuePtr pour un paramètre de données au niveau de l’exécution et un code de retour de SQL_NEED_DATA. Lorsque toutes les données de paramètre ont été transmises au pilote, SQLParamData retourne SQL_SUCCESS, SQL_SUCCESS_WITH_INFO ou SQL_ERROR. Pour les paramètres de données au niveau de l’exécution, ParameterValuePtr, qui est identique au champ de descripteur SQL_DESC_DATA_PTR, peuvent être considérés comme un jeton pour identifier un paramètre pour lequel une valeur est requise de manière unique. Ce « jeton » est passé de l'application au pilote au moment de la liaison, puis repassé à l'application au moment de l'exécution.
  4. Pour envoyer des données de ligne de paramètre table pour les paramètres table null, si le paramètre table n’a pas de lignes, une application appelle SQLPutData avec StrLen_or_Ind définie sur SQL_DEFAULT_PARAM .

    Pour les paramètres table non nuls, une application :

    • Définit Str_Len_or_Ind pour toutes les colonnes de paramètres table sur des valeurs appropriées et remplit les mémoires tampons de données pour les colonnes de paramètres table qui ne doivent pas être des paramètres de données au niveau de l’exécution. Vous pouvez utiliser la fonctionnalité « data-at-execution » pour les colonnes de paramètres table d'une manière semblable à celle employée lorsque des paramètres ordinaires sont passés au pilote par fragments.

    • Appelle SQLPutData avec Str_Len_or_Ind défini sur le nombre de lignes à envoyer au serveur. Toute valeur en dehors de la plage 0 à SQL_DESC_ARRAY_SIZE ou SQL_DEFAULT_PARAM est une erreur et retourne SQLSTATE HY090, avec le message « Chaîne ou longueur de mémoire tampon non valide ». 0 indique que toutes les lignes ont été envoyées et qu’il n’y a plus de données pour un paramètre table (comme indiqué dans le deuxième élément de puce de cette liste). SQL_DEFAULT_PARAM peut être utilisé uniquement la première fois que le pilote demande des données pour un paramètre table (comme décrit dans le premier élément de puce dans cette liste).

  5. Lorsque toutes les lignes ont été envoyées, appelle SQLPutData pour le paramètre table avec une valeur Str_Len_or_Ind de 0, puis passez à l’étape 3a ci-dessus.

  6. Appelle à nouveau SQLParamData. S’il existe des paramètres de données au niveau de l’exécution parmi les colonnes de paramètres table, ceux-ci sont identifiés par la valeur ValuePtrPtr retournée par SQLParamData. Lorsque toutes les valeurs de colonne sont disponibles, SQLParamData retourne la valeur ParameterValuePtr pour le paramètre table et l’application recommence.

Étapes suivantes

Paramètres table ODBC