SQLSetPos, fonction

Conformité
Version introduite : Conformité aux normes ODBC 1.0 : ODBC

Résumé
SQLSetPos définit la position du curseur dans un ensemble de lignes et permet à une application d’actualiser les données dans l’ensemble de lignes ou de mettre à jour ou de supprimer des données dans le jeu de résultats.

Syntaxe

  
SQLRETURN SQLSetPos(  
      SQLHSTMT        StatementHandle,  
      SQLSETPOSIROW   RowNumber,  
      SQLUSMALLINT    Operation,  
      SQLUSMALLINT    LockType);  

Arguments

StatementHandle
[Entrée] Handle d’instruction.

RowNumber
[Entrée] Position de la ligne dans l’ensemble de lignes sur laquelle effectuer l’opération spécifiée avec l’argument Opération . Si RowNumber est 0, l’opération s’applique à chaque ligne de l’ensemble de lignes.

Pour plus d’informations, consultez « Commentaires ».

Opération
[Entrée] Opération à effectuer :

SQL_POSITION SQL_REFRESH SQL_UPDATE SQL_DELETE

Remarque

La valeur SQL_ADD de l’argument Opération a été déconseillée pour ODBC 3.x. Les pilotes ODBC 3.x devront prendre en charge SQL_ADD pour la compatibilité descendante. Cette fonctionnalité a été remplacée par un appel à SQLBulkOperations par une opération de SQL_ADD. Lorsqu’une application ODBC 3.x fonctionne avec un pilote ODBC 2.x , le Gestionnaire de pilotes mappe un appel à SQLBulkOperations avec une opération de SQL_ADD à SQLSetPos avec une opération de SQL_ADD.

Pour plus d’informations, consultez « Commentaires ».

LockType
[Entrée] Spécifie comment verrouiller la ligne après avoir effectué l’opération spécifiée dans l’argument Opération .

SQL_LOCK_NO_CHANGE SQL_LOCK_EXCLUSIVE SQL_LOCK_UNLOCK

Pour plus d’informations, consultez « Commentaires ».

Retours

SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR ou SQL_INVALID_HANDLE.

Diagnostics

Lorsque SQLSetPos retourne SQL_ERROR ou SQL_SUCCESS_WITH_INFO, une valeur SQLSTATE associée peut être obtenue en appelant SQLGetDiagRec avec un HandleType de SQL_HANDLE_STMT et un Handle of StatementHandle. Le tableau suivant répertorie les valeurs SQLSTATE couramment retournées par SQLSetPos et explique chacune d’elles dans le contexte de cette fonction ; la notation « (DM) » précède les descriptions des SQLSTATEs retournées par le Gestionnaire de pilotes. Le code de retour associé à chaque valeur SQLSTATE est SQL_ERROR, sauf indication contraire.

Pour tous les SQLSTATEs qui peuvent retourner SQL_SUCCESS_WITH_INFO ou SQL_ERROR (sauf 01xxx SQLSTATEs), SQL_SUCCESS_WITH_INFO est retourné si une erreur se produit sur une ou plusieurs lignes, mais pas toutes, les lignes d’une opération multirow et SQL_ERROR est retournée si une erreur se produit sur une opération à une seule ligne.

SQLSTATE Erreur Description
01000 Avertissement général Message d’information spécifique au pilote. (La fonction retourne SQL_SUCCESS_WITH_INFO.)
01001 Conflit d’opérations de curseur L’argument Opération a été SQL_DELETE ou SQL_UPDATE, et aucune ligne ou plusieurs lignes n’ont été supprimées ou mises à jour. (Pour plus d’informations sur les mises à jour de plusieurs lignes, consultez la description du SQL_ATTR_SIMULATE_CURSOR Attribut dans SQLSetStmtAttr.) (la fonction retourne SQL_SUCCESS_WITH_INFO.)

L’argument Opération a été SQL_DELETE ou SQL_UPDATE, et l’opération a échoué en raison de l’accès concurrentiel optimiste. (La fonction retourne SQL_SUCCESS_WITH_INFO.)
01004 Troncation de droite des données de chaîne L’argument Opération a été SQL_REFRESH, et les données de chaîne ou binaire retournées pour une colonne ou des colonnes avec un type de données de SQL_C_CHAR ou SQL_C_BINARY ont entraîné la troncation de caractères non vides ou de données binaires non NULL.
01S01 Erreur dans la ligne L’argument RowNumber a été 0 et une erreur s’est produite dans une ou plusieurs lignes lors de l’exécution de l’opération spécifiée avec l’argument Opération .

(SQL_SUCCESS_WITH_INFO est retournée si une erreur se produit sur une ou plusieurs lignes, mais pas toutes, des lignes d’une opération multirow et SQL_ERROR est retournée si une erreur se produit sur une opération à une seule ligne.)

(Ce SQLSTATE est retourné uniquement lorsque SQLSetPos est appelé après SQLExtendedFetch, si le pilote est un pilote ODBC 2.x et que la bibliothèque de curseurs n’est pas utilisée.)
01S07 Troncation fractionnelle L’argument Opération était SQL_REFRESH, le type de données de la mémoire tampon d’application n’était pas SQL_C_CHAR ou SQL_C_BINARY, et les données retournées aux mémoires tampons d’application pour une ou plusieurs colonnes ont été tronquées. Pour les types de données numériques, la partie fractionnaire du nombre a été tronquée. Pour les types de données time, timestamp et interval contenant un composant de temps, la partie fractionnaire de l’heure a été tronquée.

(La fonction retourne SQL_SUCCESS_WITH_INFO.)
07006 Violation d’attribut de type de données restreint La valeur de données d’une colonne dans le jeu de résultats n’a pas pu être convertie en type de données spécifié par TargetType dans l’appel à SQLBindCol.
07009 Index de descripteur non valide L’argument Opération était SQL_REFRESH ou SQL_UPDATE, et une colonne était liée avec un nombre de colonnes supérieur au nombre de colonnes dans le jeu de résultats.
21S02 Le degré de table dérivée ne correspond pas à la liste des colonnes L’opération d’argument était SQL_UPDATE et aucune colonne n’était modifiable, car toutes les colonnes étaient non liées, en lecture seule ou la valeur de la mémoire tampon de longueur/indicateur liée était SQL_COLUMN_IGNORE.
22001 Données de chaîne, troncation droite L’argument Opération a été SQL_UPDATE, et l’affectation d’un caractère ou d’une valeur binaire à une colonne a entraîné la troncation de caractères non vides (pour les caractères) ou non null (pour les caractères binaires) ou d’octets.
22003 Valeur numérique hors plage L’argument Opération a été SQL_UPDATE, et l’affectation d’une valeur numérique à une colonne dans le jeu de résultats a provoqué la troncation de l’ensemble (par opposition à la fraction) du nombre.

L’opération d’argument a été SQL_REFRESH, et le renvoi de la valeur numérique pour une ou plusieurs colonnes liées aurait provoqué une perte de chiffres significatifs.
22007 Format datetime non valide L’argument Opération a été SQL_UPDATE, et l’affectation d’une valeur de date ou d’horodatage à une colonne dans le jeu de résultats a provoqué l’expiration du champ année, mois ou jour.

L’argument Opération a été SQL_REFRESH, et le renvoi de la valeur date ou timestamp pour une ou plusieurs colonnes liées aurait provoqué l’absence de plage du champ année, mois ou jour.
22008 Dépassement de champ date/heure L’argument Opération a été SQL_UPDATE et les performances de l’arithmétique datetime sur les données envoyées à une colonne dans le jeu de résultats ont entraîné un champ datetime (année, mois, jour, heure, minute ou deuxième champ) du résultat en dehors de la plage autorisée de valeurs pour le champ, ou étant non valide en fonction des règles naturelles du calendrier grégorien pour les datetimes.

L’argument Opération a été SQL_REFRESH et les performances de l’arithmétique datetime sur les données récupérées à partir du jeu de résultats ont entraîné un champ datetime (année, mois, jour, heure, minute ou seconde) du résultat en dehors de la plage autorisée de valeurs pour le champ, ou étant non valide en fonction des règles naturelles du calendrier grégorien pour les datestimes.
22015 Dépassement de champ d’intervalle L’argument Opération a été SQL_UPDATE et l’affectation d’un type C numérique ou d’intervalle exact à un type de données SQL d’intervalle a provoqué une perte de chiffres significatifs.

L’argument Opération était SQL_UPDATE ; lors de l’affectation à un type SQL d’intervalle, il n’y avait aucune représentation de la valeur du type C dans le type SQL d’intervalle.

L’argument Opération a été SQL_REFRESH et l’affectation d’un type SQL numérique ou d’intervalle exact à un type C d’intervalle a provoqué une perte de chiffres significatifs dans le champ de début.

L’argument Opération était SQL_ REFRESH ; lors de l’affectation à un type C d’intervalle, il n’y avait aucune représentation de la valeur du type SQL dans le type C d’intervalle.
22018 Valeur de caractère non valide pour la spécification de cast L’argument Opération était SQL_REFRESH ; le type C était un nombre exact ou approximatif, une datetime ou un type de données d’intervalle ; le type SQL de la colonne était un type de données caractère ; et la valeur de la colonne n’était pas un littéral valide du type C lié.

L’argument Opération était SQL_UPDATE ; le type SQL était un nombre exact ou approximatif, une datetime ou un type de données d’intervalle ; le type C était SQL_C_CHAR ; et la valeur de la colonne n’était pas un littéral valide du type SQL lié.
23000 Violation de contrainte d’intégrité L’argument Opération a été SQL_DELETE ou SQL_UPDATE, et une contrainte d’intégrité a été violée.
24 000 État de curseur non valide L’instruction StatementHandle était dans un état exécuté, mais aucun jeu de résultats n’a été associé à l’instruction StatementHandle.

(DM) Un curseur a été ouvert sur StatementHandle, mais SQLFetch ou SQLFetchScroll n’avait pas été appelé.

Un curseur a été ouvert sur StatementHandle et SQLFetch ou SQLFetchScroll avait été appelé, mais le curseur était positionné avant le début du jeu de résultats ou après la fin du jeu de résultats.

L’argument Opération a été SQL_DELETE, SQL_REFRESH ou SQL_UPDATE, et le curseur a été positionné avant le début du jeu de résultats ou après la fin du jeu de résultats.
40001 Échec de sérialisation La transaction a été restaurée en raison d’un interblocage de ressources avec une autre transaction.
40003 Saisie semi-automatique de l’instruction inconnue La connexion associée a échoué pendant l’exécution de cette fonction et l’état de la transaction ne peut pas être déterminé.
42000 Erreur de syntaxe ou violation d’accès Le pilote n’a pas pu verrouiller la ligne si nécessaire pour effectuer l’opération demandée dans l’argument Opération.

Le pilote n’a pas pu verrouiller la ligne comme demandé dans l’argument LockType.
44000 Violation de WITH CHECK OPTION L’argument Opération a été SQL_UPDATE, et la mise à jour a été effectuée sur une table vue ou une table dérivée de la table vue qui a été créée en spécifiant WITH CHECK OPTION, de sorte qu’une ou plusieurs lignes affectées par la mise à jour ne seront plus présentes dans la table vue.
HY000 Erreur générale Une erreur s’est produite pour laquelle il n’y avait aucun SQLSTATE spécifique et pour lequel aucun SQLSTATE spécifique à l’implémentation n’a été défini. Le message d’erreur retourné par SQLGetDiagRec dans la mémoire tampon *MessageText décrit l’erreur et sa cause.
HY001 Erreur d’allocation de mémoire Le pilote n’a pas pu allouer de mémoire nécessaire pour prendre en charge l’exécution ou l’achèvement de la fonction.
HY008 Opération annulée Le traitement asynchrone a été activé pour StatementHandle. La fonction a été appelée, et avant qu’elle ait terminé l’exécution, SQLCancel ou SQLCancelHandle a été appelée sur l’InstructionHandle, puis la fonction a été appelée à nouveau sur l’InstructionHandle.

La fonction a été appelée et avant qu’elle ait terminé l’exécution, SQLCancel ou SQLCancelHandle a été appelée sur l’InstructionHandle à partir d’un autre thread dans une application multithread.
HY010 Erreur de séquence de fonction (DM) Une fonction en cours d’exécution asynchrone a été appelée pour le handle de connexion associé à StatementHandle. Cette fonction asynchrone était toujours en cours d’exécution lorsque la fonction SQLSetPos a été appelée.

(DM) L’instruction StatementHandle spécifiée n’était pas dans un état exécuté. La fonction a été appelée sans appeler SQLExecDirect, SQLExecute ou une fonction de catalogue.

(DM) Une fonction en cours d’exécution asynchrone (et non celle-ci) a été appelée pour l’instruction StatementHandle et était toujours en cours d’exécution lorsque cette fonction a été appelée.

(DM) SQLExecute, SQLExecDirect, SQLBulkOperations ou SQLSetPos a été appelé pour l’instructionHandle et retourné SQL_NEED_DATA. Cette fonction a été appelée avant que les données ne soient envoyées pour tous les paramètres ou colonnes de données à l’exécution.

(DM) Le pilote était un pilote ODBC 2.x , et SQLSetPos était appelé pour un StatementHandle après l’appel de SQLFetch .
HY011 Impossible de définir l’attribut maintenant (DM) Le pilote était un pilote ODBC 2.x ; l’attribut d’instruction SQL_ATTR_ROW_STATUS_PTR a été défini ; puis SQLSetPos a été appelé avant SQLFetch, SQLFetchScroll ou SQLExtendedFetch a été appelé.
HY013 Erreur de gestion de la mémoire L’appel de fonction n’a pas pu être traité, car les objets de mémoire sous-jacents n’ont pas pu être accessibles, éventuellement en raison de conditions de mémoire insuffisantes.
HY090 Longueur de la chaîne ou de la mémoire tampon non valide L’argument Opération était SQL_UPDATE, une valeur de données était un pointeur Null et la valeur de longueur de colonne n’était pas 0, SQL_DATA_AT_EXEC, SQL_COLUMN_IGNORE, SQL_NULL_DATA ou inférieure ou égale à SQL_LEN_DATA_AT_EXEC_OFFSET.

L’argument Opération était SQL_UPDATE ; une valeur de données n’était pas un pointeur Null ; le type de données C était SQL_C_BINARY ou SQL_C_CHAR ; et la valeur de longueur de colonne était inférieure à 0, mais pas égale à SQL_DATA_AT_EXEC, SQL_COLUMN_IGNORE, SQL_NTS ou SQL_NULL_DATA, ou inférieure ou égale à SQL_LEN_DATA_AT_EXEC_OFFSET.

La valeur d’une mémoire tampon de longueur/indicateur a été SQL_DATA_AT_EXEC ; le type SQL était SQL_LONGVARCHAR, SQL_LONGVARBINARY ou un type de données spécifique à une source de données longue ; et le type d’informations SQL_NEED_LONG_DATA_LEN dans SQLGetInfo était « Y ».
HY092 Identificateur d’attribut non valide (DM) La valeur spécifiée pour l’argument Opération n’était pas valide.

(DM) La valeur spécifiée pour l’argument LockType n’était pas valide.

L’argument Opération était SQL_UPDATE ou SQL_DELETE, et l’attribut d’instruction SQL_ATTR_CONCURRENCY était SQL_ATTR_CONCUR_READ_ONLY.
HY107 Valeur de ligne hors plage La valeur spécifiée pour l’argument RowNumber était supérieure au nombre de lignes de l’ensemble de lignes.
HY109 Position du curseur non valide Le curseur associé à l’instruction StatementHandle a été défini en tant que transfert uniquement. Le curseur n’a donc pas pu être positionné dans l’ensemble de lignes. Consultez la description de l’attribut SQL_ATTR_CURSOR_TYPE dans SQLSetStmtAttr.

L’argument Opération était SQL_UPDATE, SQL_DELETE ou SQL_REFRESH, et la ligne identifiée par l’argument RowNumber avait été supprimée ou n’avait pas été extraite.

(DM) L’argument RowNumber était 0 et l’argument Opération était SQL_POSITION.

SQLSetPos a été appelé après que SQLBulkOperations a été appelé et avant que SQLFetchScroll ou SQLFetch ait été appelé.
HY117 La connexion est suspendue en raison d’un état de transaction inconnu. Seules les fonctions de déconnexion et de lecture seule sont autorisées. (DM) Pour plus d’informations sur l’état suspendu, consultez la fonction SQLEndTran.
HYC00 Fonctionnalité facultative non implémentée Le pilote ou la source de données ne prend pas en charge l’opération demandée dans l’argument Opération ou l’argument LockType .
HYT00 Délai expiré La période d’expiration de la requête a expiré avant que la source de données ne retourne le jeu de résultats. La période d’expiration est définie via SQLSetStmtAttr avec un attribut de SQL_ATTR_QUERY_TIMEOUT.
HYT01 Délai d’attente de la connexion expiré La période d’expiration de la connexion a expiré avant que la source de données ne réponde à la demande. La période d’expiration de connexion est définie via SQLSetConnectAttr, SQL_ATTR_CONNECTION_TIMEOUT.
IM001 Le pilote ne prend pas en charge cette fonction (DM) Le pilote associé à StatementHandle ne prend pas en charge la fonction.
IM017 L’interrogation est désactivée en mode de notification asynchrone Chaque fois que le modèle de notification est utilisé, l’interrogation est désactivée.
IM018 SQLCompleteAsync n’a pas été appelé pour terminer l’opération asynchrone précédente sur ce handle. Si l’appel de fonction précédent sur le handle retourne SQL_STILL_EXECUTING et si le mode de notification est activé, SQLCompleteAsync doit être appelé sur le handle pour effectuer un post-traitement et terminer l’opération.

Commentaires

Attention

Pour plus d’informations sur l’instruction indique que SQLSetPos peut être appelé et ce qu’il doit faire pour la compatibilité avec les applications ODBC 2.x , consultez Curseurs de bloc, curseurs à défilement et compatibilité descendante.

RowNumber, argument

L’argument RowNumber spécifie le nombre de lignes de l’ensemble de lignes sur lequel effectuer l’opération spécifiée par l’argument Opération . Si RowNumber est 0, l’opération s’applique à chaque ligne de l’ensemble de lignes. RowNumber doit être une valeur comprise entre 0 et le nombre de lignes de l’ensemble de lignes.

Remarque

Dans le langage C, les tableaux sont basés sur 0 et l’argument RowNumber est basé sur 1. Par exemple, pour mettre à jour la cinquième ligne de l’ensemble de lignes, une application modifie les mémoires tampons de l’ensemble de lignes à l’index de tableau 4, mais spécifie un Numéro de ligne de 5.

Toutes les opérations positionnent le curseur sur la ligne spécifiée par RowNumber. Les opérations suivantes nécessitent une position de curseur :

  • Instructions de mise à jour et de suppression positionnées.

  • Appels à SQLGetData.

  • Appels à SQLSetPos avec les options SQL_DELETE, SQL_REFRESH et SQL_UPDATE.

Par exemple, si RowNumber est 2 pour un appel à SQLSetPos avec une opération de SQL_DELETE, le curseur est positionné sur la deuxième ligne de l’ensemble de lignes et cette ligne est supprimée. L’entrée dans le tableau d’état de ligne d’implémentation (pointée par l’attribut d’instruction SQL_ATTR_ROW_STATUS_PTR) pour la deuxième ligne est remplacée par SQL_ROW_DELETED.

Une application peut spécifier une position de curseur lorsqu’elle appelle SQLSetPos. En règle générale, il appelle SQLSetPos avec l’opération SQL_POSITION ou SQL_REFRESH pour positionner le curseur avant d’exécuter une instruction de mise à jour ou de suppression positionnée ou d’appeler SQLGetData.

Argument d’opération

L’argument Opération prend en charge les opérations suivantes. Pour déterminer les options prises en charge par une source de données, une application appelle SQLGetInfo avec le type d’informations SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, SQL_KEYSET_CURSOR_ATTRIBUTES1 ou SQL_STATIC_CURSOR_ATTRIBUTES1 (selon le type du curseur).

Opération

argument
Opération
SQL_POSITION Le pilote positionne le curseur sur la ligne spécifiée par RowNumber.

Le contenu du tableau d’état de ligne pointé par l’attribut d’instruction SQL_ATTR_ROW_OPERATION_PTR est ignoré pour l’opération de SQL_POSITION.
SQL_REFRESH Le pilote positionne le curseur sur la ligne spécifiée par RowNumber et actualise les données dans les mémoires tampons de l’ensemble de lignes pour cette ligne. Pour plus d’informations sur la façon dont le pilote retourne des données dans les mémoires tampons d’ensemble de lignes, consultez les descriptions de liaisons en ligne et en colonnes dans SQLBindCol.

SQLSetPos avec une opération de SQL_REFRESH met à jour l’état et le contenu des lignes dans l’ensemble de lignes récupéré actuel. Cela inclut l’actualisation des signets. Étant donné que les données dans les mémoires tampons sont actualisées, mais pas réédifiées, l’appartenance à l’ensemble de lignes est fixe. Cela est différent de l’actualisation effectuée par un appel à SQLFetchScroll avec une FetchOrientation de SQL_FETCH_RELATIVE et un RowNumber égal à 0, ce qui réfète l’ensemble de lignes du jeu de résultats afin qu’il puisse afficher les données ajoutées et supprimer des données supprimées si ces opérations sont prises en charge par le pilote et le curseur.

Une actualisation réussie avec SQLSetPos ne modifie pas l’état d’une ligne de SQL_ROW_DELETED. Les lignes supprimées dans l’ensemble de lignes continueront d’être marquées comme supprimées jusqu’à la récupération suivante. Les lignes disparaissent lors de la récupération suivante si le curseur prend en charge l’empaqueter (dans lequel un SQLFetch ou SQLFetchScroll ultérieur ne retourne pas de lignes supprimées).

Les lignes ajoutées n’apparaissent pas lorsqu’une actualisation avec SQLSetPos est effectuée. Ce comportement est différent de SQLFetchScroll avec un FetchType de SQL_FETCH_RELATIVE et un RowNumber égal à 0, qui actualise également l’ensemble de lignes actuel, mais affiche les enregistrements ajoutés ou les enregistrements supprimés de pack si ces opérations sont prises en charge par le curseur.

Une actualisation réussie avec SQLSetPos modifie l’état d’une ligne de SQL_ROW_ADDED en SQL_ROW_SUCCESS (si le tableau d’état de ligne existe).

Une actualisation réussie avec SQLSetPos modifie l’état d’une ligne de SQL_ROW_UPDATED par le nouvel état de la ligne (si le tableau d’état de ligne existe).

Si une erreur se produit dans une opération SQLSetPos sur une ligne, l’état de la ligne est défini sur SQL_ROW_ERROR (si le tableau d’état de ligne existe).

Pour un curseur ouvert avec un attribut d’instruction SQL_ATTR_CONCURRENCY de SQL_CONCUR_ROWVER ou de SQL_CONCUR_VALUES, une actualisation avec SQLSetPos peut mettre à jour les valeurs d’accès concurrentiel optimistes utilisées par la source de données pour détecter que la ligne a changé. Si cela se produit, les versions ou valeurs de ligne utilisées pour garantir la concurrence des curseurs sont mises à jour chaque fois que les mémoires tampons d’ensemble de lignes sont actualisées à partir du serveur. Cela se produit pour chaque ligne actualisée.

Le contenu du tableau d’état de ligne pointé par l’attribut d’instruction SQL_ATTR_ROW_OPERATION_PTR est ignoré pour l’opération de SQL_REFRESH.
SQL_UPDATE Le pilote positionne le curseur sur la ligne spécifiée par RowNumber et met à jour la ligne sous-jacente de données avec les valeurs des mémoires tampons de l’ensemble de lignes (argument TargetValuePtr dans SQLBindCol). Il récupère les longueurs des données à partir des mémoires tampons longueur/indicateur (argument StrLen_or_IndPtr dans SQLBindCol). Si la longueur d’une colonne est SQL_COLUMN_IGNORE, la colonne n’est pas mise à jour. Après avoir mis à jour la ligne, le pilote modifie l’élément correspondant du tableau d’état de ligne en SQL_ROW_UPDATED ou SQL_ROW_SUCCESS_WITH_INFO (si le tableau d’état de ligne existe).

Il est défini par le pilote ce que le comportement est si SQLSetPos avec un argument Opération de SQL_UPDATE est appelé sur un curseur qui contient des colonnes en double. Le pilote peut retourner un SQLSTATE défini par le pilote, peut mettre à jour la première colonne qui apparaît dans le jeu de résultats ou effectuer d’autres comportements définis par le pilote.

Le tableau d’opérations de ligne pointé par l’attribut d’instruction SQL_ATTR_ROW_OPERATION_PTR peut être utilisé pour indiquer qu’une ligne dans l’ensemble de lignes actuel doit être ignorée lors d’une mise à jour en bloc. Pour plus d’informations, consultez « Status and Operation Arrays » plus loin dans cette référence de fonction.
SQL_DELETE Le pilote positionne le curseur sur la ligne spécifiée par RowNumber et supprime la ligne sous-jacente des données. Il modifie l’élément correspondant du tableau d’état de ligne en SQL_ROW_DELETED. Une fois la ligne supprimée, les éléments suivants ne sont pas valides pour la ligne : instructions de mise à jour et de suppression positionnées, appels à SQLGetData et appels à SQLSetPos avec Opération définie sur n’importe quoi sauf SQL_POSITION. Pour les pilotes qui prennent en charge l’empaquetage, la ligne est supprimée du curseur lorsque de nouvelles données sont récupérées à partir de la source de données.

Si la ligne reste visible dépend du type de curseur. Par exemple, les lignes supprimées sont visibles par les curseurs statiques et pilotés par les jeux de clés, mais invisibles pour les curseurs dynamiques.

Le tableau d’opérations de ligne pointé par l’attribut d’instruction SQL_ATTR_ROW_OPERATION_PTR peut être utilisé pour indiquer qu’une ligne dans l’ensemble de lignes actuel doit être ignorée lors d’une suppression en bloc. Pour plus d’informations, consultez « Status and Operation Arrays » plus loin dans cette référence de fonction.

LockType, argument

L’argument LockType permet aux applications de contrôler l’accès concurrentiel. Dans la plupart des cas, les sources de données qui prennent en charge les niveaux d’accès concurrentiel et les transactions prennent uniquement en charge la valeur SQL_LOCK_NO_CHANGE de l’argument LockType . L’argument LockType est généralement utilisé uniquement pour la prise en charge basée sur les fichiers.

L’argument LockType spécifie l’état de verrouillage de la ligne après l’exécution de SQLSetPos . Si le pilote ne parvient pas à verrouiller la ligne pour effectuer l’opération demandée ou pour satisfaire l’argument LockType , il retourne SQL_ERROR et SQLSTATE 42000 (erreur de syntaxe ou violation d’accès).

Bien que l’argument LockType soit spécifié pour une instruction unique, le verrou accorde les mêmes privilèges à toutes les instructions sur la connexion. En particulier, un verrou acquis par une instruction sur une connexion peut être déverrouillé par une autre instruction sur la même connexion.

Une ligne verrouillée via SQLSetPos reste verrouillée jusqu’à ce que l’application appelle SQLSetPos pour la ligne avec LockType défini sur SQL_LOCK_UNLOCK, ou jusqu’à ce que l’application appelle SQLFreeHandle pour l’instruction ou SQLFreeStmt avec l’option SQL_CLOSE. Pour un pilote qui prend en charge les transactions, une ligne verrouillée via SQLSetPos est déverrouillée lorsque l’application appelle SQLEndTran pour valider ou restaurer une transaction sur la connexion (si un curseur est fermé lorsqu’une transaction est validée ou restaurée, comme indiqué par l’SQL_CURSOR_COMMIT_BEHAVIOR et SQL_CURSOR_ROLLBACK_BEHAVIOR types d’informations retournés par SQLGetInfo).

L’argument LockType prend en charge les types de verrous suivants. Pour déterminer quels verrous sont pris en charge par une source de données, une application appelle SQLGetInfo avec les SQL_DYNAMIC_CURSOR_ATTRIBUTES1, SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1, SQL_KEYSET_CURSOR_ATTRIBUTES1 ou SQL_STATIC_CURSOR_ATTRIBUTES1 type d’informations (selon le type du curseur).

Argument LockType Type de verrou
SQL_LOCK_NO_CHANGE Le pilote ou la source de données garantit que la ligne est dans le même état verrouillé ou déverrouillé qu’avant l’appel de SQLSetPos . Cette valeur de LockType permet aux sources de données qui ne prennent pas en charge le verrouillage explicite au niveau des lignes d’utiliser les verrous requis par les niveaux d’isolation concurrentiel et transactionnels actuels.
SQL_LOCK_EXCLUSIVE Le pilote ou la source de données verrouille la ligne exclusivement. Une instruction sur une autre connexion ou dans une autre application ne peut pas être utilisée pour acquérir des verrous sur la ligne.
SQL_LOCK_UNLOCK Le pilote ou la source de données déverrouille la ligne.

Si un pilote prend en charge SQL_LOCK_EXCLUSIVE mais ne prend pas en charge SQL_LOCK_UNLOCK, une ligne verrouillée reste verrouillée jusqu’à ce qu’un des appels de fonction décrits dans le paragraphe précédent se produise.

Si un pilote prend en charge SQL_LOCK_EXCLUSIVE mais ne prend pas en charge SQL_LOCK_UNLOCK, une ligne verrouillée reste verrouillée jusqu’à ce que l’application appelle SQLFreeHandle pour l’instruction ou SQLFreeStmt avec l’option SQL_CLOSE. Si le pilote prend en charge les transactions et ferme le curseur lors de la validation ou de la restauration de la transaction, l’application appelle SQLEndTran.

Pour les opérations de mise à jour et de suppression dans SQLSetPos, l’application utilise l’argument LockType comme suit :

  • Pour garantir qu’une ligne ne change pas après sa récupération, une application appelle SQLSetPos avec l’opération définie sur SQL_REFRESH et LockType définie sur SQL_LOCK_EXCLUSIVE.

  • Si l’application définit LockType sur SQL_LOCK_NO_CHANGE, le pilote garantit qu’une opération de mise à jour ou de suppression réussit uniquement si l’application spécifiée SQL_CONCUR_LOCK pour l’attribut d’instruction SQL_ATTR_CONCURRENCY.

  • Si l’application spécifie SQL_CONCUR_ROWVER ou SQL_CONCUR_VALUES pour l’attribut d’instruction SQL_ATTR_CONCURRENCY, le pilote compare les versions ou valeurs de ligne et rejette l’opération si la ligne a changé depuis l’extraction de la ligne par l’application.

  • Si l’application spécifie SQL_CONCUR_READ_ONLY pour l’attribut d’instruction SQL_ATTR_CONCURRENCY, le pilote rejette toute opération de mise à jour ou de suppression.

Pour plus d’informations sur l’attribut d’instruction SQL_ATTR_CONCURRENCY, consultez SQLSetStmtAttr.

Tableaux d’état et d’opération

Les tableaux d’état et d’opération suivants sont utilisés lors de l’appel de SQLSetPos :

  • Le tableau d’état de ligne (comme indiqué par le champ SQL_DESC_ARRAY_STATUS_PTR dans l’IRD et l’attribut d’instruction SQL_ATTR_ROW_STATUS_ARRAY) contient des valeurs d’état pour chaque ligne de données de l’ensemble de lignes. Le pilote définit les valeurs d’état dans ce tableau après un appel à SQLFetch, SQLFetchScroll, SQLBulkOperations ou SQLSetPos. Ce tableau est pointé par l’attribut d’instruction SQL_ATTR_ROW_STATUS_PTR.

  • Le tableau d’opérations de ligne (comme indiqué par le champ SQL_DESC_ARRAY_STATUS_PTR dans l’attribut ARD et l’attribut d’instruction SQL_ATTR_ROW_OPERATION_ARRAY) contient une valeur pour chaque ligne de l’ensemble de lignes qui indique si un appel à SQLSetPos pour une opération en bloc est ignoré ou effectué. Chaque élément du tableau est défini sur SQL_ROW_PROCEED (valeur par défaut) ou SQL_ROW_IGNORE. Ce tableau est pointé par l’attribut d’instruction SQL_ATTR_ROW_OPERATION_PTR.

Le nombre d’éléments dans les tableaux d’état et d’opération doit être égal au nombre de lignes de l’ensemble de lignes (tel que défini par l’attribut d’instruction SQL_ATTR_ROW_ARRAY_SIZE).

Pour plus d’informations sur le tableau d’état de ligne, consultez SQLFetch. Pour plus d’informations sur le tableau d’opérations de ligne, consultez « Ignorer une ligne dans une opération en bloc », plus loin dans cette section.

Utilisation de SQLSetPos

Avant qu’une application appelle SQLSetPos, elle doit effectuer la séquence d’étapes suivante :

  1. Si l’application appelle SQLSetPos avec l’opération définie sur SQL_UPDATE, appelez SQLBindCol (ou SQLSetDescRec) pour chaque colonne afin de spécifier son type de données et de lier des mémoires tampons pour les données et la longueur de la colonne.

  2. Si l’application appelle SQLSetPos avec l’opération définie sur SQL_DELETE ou SQL_UPDATE, appelez SQLColAttribute pour vous assurer que les colonnes à supprimer ou à mettre à jour sont mises à jour.

  3. Appelez SQLExecDirect, SQLExecute ou une fonction de catalogue pour créer un jeu de résultats.

  4. Appelez SQLFetch ou SQLFetchScroll pour récupérer les données.

Pour plus d’informations sur l’utilisation de SQLSetPos, consultez Mise à jour des données avec SQLSetPos.

Suppression de données à l’aide de SQLSetPos

Pour supprimer des données avec SQLSetPos, une application appelle SQLSetPos avec RowNumber défini sur le nombre de lignes à supprimer et l’opération définie sur SQL_DELETE.

Une fois les données supprimées, le pilote modifie la valeur dans le tableau d’état de ligne d’implémentation pour que la ligne appropriée soit SQL_ROW_DELETED (ou SQL_ROW_ERROR).

Mise à jour des données à l’aide de SQLSetPos

Une application peut transmettre la valeur d’une colonne dans la mémoire tampon de données liée ou avec un ou plusieurs appels à SQLPutData. Les colonnes dont les données sont transmises avec SQLPutData sont appelées colonnes data-at-execution. Elles sont couramment utilisées pour envoyer des données pour SQL_LONGVARBINARY et SQL_LONGVARCHAR colonnes et peuvent être mélangées à d’autres colonnes.

Pour mettre à jour des données avec SQLSetPos, une application :

  1. Place les valeurs dans les mémoires tampons de données et de longueur/indicateur liées à SQLBindCol :

    • Pour les colonnes normales, l’application place la nouvelle valeur de colonne dans la mémoire tampon *TargetValuePtr et la longueur de cette valeur dans la mémoire tampon *StrLen_or_IndPtr . Si la ligne ne doit pas être mise à jour, l’application place SQL_ROW_IGNORE dans l’élément de cette ligne du tableau d’opérations de ligne.

    • Pour les colonnes de données au niveau de l’exécution, l’application place une valeur définie par l’application, telle que le numéro de colonne, dans la mémoire tampon *TargetValuePtr . La valeur peut être utilisée ultérieurement pour identifier la colonne.

      L’application place le résultat de la macro SQL_LEN_DATA_AT_EXEC(length) dans la mémoire tampon *StrLen_or_IndPtr . Si le type de données SQL de la colonne est SQL_LONGVARBINARY, SQL_LONGVARCHAR ou un type de données spécifique à une source de données longue et que le pilote retourne « Y » pour le type d’informations SQL_NEED_LONG_DATA_LEN dans SQLGetInfo, la longueur correspond au nombre d’octets de données à envoyer pour le paramètre ; sinon, elle doit être une valeur non négative et est ignorée.

  2. Appelle SQLSetPos avec l’argument Operation défini sur SQL_UPDATE pour mettre à jour la ligne de données.

    • S’il n’existe aucune colonne de données au niveau de l’exécution, le processus est terminé.

    • S’il existe des colonnes de données au niveau de l’exécution, la fonction retourne SQL_NEED_DATA et passe à l’étape 3.

  3. Appelle SQLParamData pour récupérer l’adresse de la mémoire tampon *TargetValuePtr pour que la première colonne de données à l’exécution soit traitée. SQLParamData retourne SQL_NEED_DATA. L’application récupère la valeur définie par l’application à partir de la mémoire tampon *TargetValuePtr .

    Remarque

    Bien que les paramètres de données à l’exécution soient similaires aux colonnes data-at-execution, la valeur retournée par SQLParamData est différente pour chacune d’elles.

    Remarque

    Les paramètres de données au niveau de l’exécution sont des paramètres dans une instruction SQL pour laquelle les données seront envoyées avec SQLPutData lorsque l’instruction est exécutée avec SQLExecDirect ou SQLExecute. Ils sont liés à SQLBindParameter ou en définissant des descripteurs avec SQLSetDescRec. La valeur retournée par SQLParamData est une valeur 32 bits passée à SQLBindParameter dans l’argument ParameterValuePtr .

    Remarque

    Les colonnes data-at-execution sont des colonnes dans un ensemble de lignes pour lequel les données seront envoyées avec SQLPutData lorsqu’une ligne est mise à jour avec SQLSetPos. Elles sont liées à SQLBindCol. La valeur retournée par SQLParamData est l’adresse de la ligne dans la mémoire tampon *TargetValuePtr en cours de traitement.

  4. Appelle SQLPutData une ou plusieurs fois pour envoyer des données pour la colonne. Plusieurs appels sont nécessaires si toutes les valeurs de données ne peuvent pas être retournées dans la mémoire tampon *TargetValuePtr spécifiée dans SQLPutData ; plusieurs appels à SQLPutData pour la même colonne sont autorisés uniquement lors de l’envoi de données C de caractère à une colonne avec un type de données spécifique à une source de données, ou lors de l’envoi de données C binaires à une colonne avec un caractère, type de données binaire ou spécifique à la source de données.

  5. Appelle à nouveau SQLParamData pour signaler que toutes les données ont été envoyées pour la colonne.

    • S’il existe davantage de colonnes de données à l’exécution, SQLParamData retourne SQL_NEED_DATA et l’adresse de la mémoire tampon TargetValuePtr pour que la colonne de données à l’exécution suivante soit traitée. L’application répète les étapes 4 et 5.

    • S’il n’y a plus de colonnes de données au niveau de l’exécution, le processus est terminé. Si l’instruction a été exécutée correctement, SQLParamData retourne SQL_SUCCESS ou SQL_SUCCESS_WITH_INFO ; si l’exécution a échoué, elle retourne SQL_ERROR. À ce stade, SQLParamData peut retourner n’importe quel SQLSTATE qui peut être retourné par SQLSetPos.

Si des données ont été mises à jour, le pilote modifie la valeur dans le tableau d’état de ligne d’implémentation pour que la ligne appropriée soit SQL_ROW_UPDATED.

Si l’opération est annulée ou qu’une erreur se produit dans SQLParamData ou SQLPutData, après que SQLSetPos retourne SQL_NEED_DATA et avant que les données ne soient envoyées pour toutes les colonnes de données à l’exécution, l’application peut appeler uniquement SQLCancel, SQLGetDiagField, SQLGetDiagRec, SQLGetFunctions, SQLParamData ou SQLPutData pour l’instruction ou la connexion associée à l’instruction. Si elle appelle une autre fonction pour l’instruction ou la connexion associée à l’instruction, la fonction retourne SQL_ERROR et SQLSTATE HY010 (erreur de séquence de fonction).

Si l’application appelle SQLCancel alors que le pilote a toujours besoin de données pour les colonnes de données à l’exécution, le pilote annule l’opération. L’application peut ensuite appeler à nouveau SQLSetPos ; l’annulation n’affecte pas l’état du curseur ou la position actuelle du curseur.

Lorsque la liste SELECT de la spécification de requête associée au curseur contient plusieurs références à la même colonne, qu’une erreur soit générée ou que le pilote ignore les références dupliquées et effectue les opérations demandées est définie par le pilote.

Exécution d’opérations en bloc

Si l’argument RowNumber est 0, le pilote effectue l’opération spécifiée dans l’argument Opération pour chaque ligne de l’ensemble de lignes dont la valeur est SQL_ROW_PROCEED dans son champ dans le tableau d’opérations de ligne pointée par SQL_ATTR_ROW_OPERATION_PTR attribut d’instruction. Il s’agit d’une valeur valide de l’argument RowNumber pour un argument Operation de SQL_DELETE, de SQL_REFRESH ou de SQL_UPDATE, mais pas SQL_POSITION. SQLSetPos avec une opération de SQL_POSITION et un numéro de ligne égal à 0 retourne SQLSTATE HY109 (position de curseur non valide).

Si une erreur se produit qui se rapporte à l’ensemble de lignes entier, tel que SQLSTATE HYT00 (délai d’expiration), le pilote retourne SQL_ERROR et le SQLSTATE approprié. Le contenu des mémoires tampons d’ensemble de lignes n’est pas défini et la position du curseur n’est pas modifiée.

Si une erreur se produit qui se rapporte à une seule ligne, le pilote :

  • Définit l’élément de la ligne dans le tableau d’état de ligne pointé par l’attribut d’instruction SQL_ATTR_ROW_STATUS_PTR sur SQL_ROW_ERROR.

  • Publie un ou plusieurs SQLSTATEs supplémentaires pour l’erreur dans la file d’attente d’erreurs et définit le champ SQL_DIAG_ROW_NUMBER dans la structure des données de diagnostic.

Après avoir traité l’erreur ou l’avertissement, si le pilote termine l’opération pour les lignes restantes de l’ensemble de lignes, elle retourne SQL_SUCCESS_WITH_INFO. Ainsi, pour chaque ligne qui a retourné une erreur, la file d’attente d’erreurs contient zéro ou plusieurs SQLSTATEs supplémentaires. Si le pilote arrête l’opération après avoir traité l’erreur ou l’avertissement, il retourne SQL_ERROR.

Si le pilote retourne des avertissements, tels que SQLSTATE 01004 (données tronquées), il retourne des avertissements qui s’appliquent à l’ensemble de lignes entier ou à des lignes inconnues dans l’ensemble de lignes avant de renvoyer les informations d’erreur qui s’appliquent à des lignes spécifiques. Elle retourne des avertissements pour des lignes spécifiques ainsi que d’autres informations d’erreur sur ces lignes.

Si RowNumber est égal à 0 et que l’opération est SQL_UPDATE, SQL_REFRESH ou SQL_DELETE, le nombre de lignes sur lesquelles SQLSetPos opère est pointé par l’attribut d’instruction SQL_ATTR_ROWS_FETCHED_PTR.

Si RowNumber est égal à 0 et que l’opération est SQL_DELETE, SQL_REFRESH ou SQL_UPDATE, la ligne actuelle après l’opération est identique à la ligne actuelle avant l’opération.

Ignorer une ligne dans une opération en bloc

Le tableau d’opérations de ligne peut être utilisé pour indiquer qu’une ligne dans l’ensemble de lignes actuel doit être ignorée pendant une opération en bloc à l’aide de SQLSetPos. Pour diriger le pilote pour ignorer une ou plusieurs lignes pendant une opération en bloc, une application doit effectuer les étapes suivantes :

  1. Appelez SQLSetStmtAttr pour définir l’attribut d’instruction SQL_ATTR_ROW_OPERATION_PTR pour qu’il pointe vers un tableau de SQLUSMALLINTs. Ce champ peut également être défini en appelant SQLSetDescField pour définir le champ d’en-tête SQL_DESC_ARRAY_STATUS_PTR de l’ARD, ce qui nécessite qu’une application obtienne le handle de descripteur.

  2. Définissez chaque élément du tableau d’opérations de ligne sur l’une des deux valeurs suivantes :

    • SQL_ROW_IGNORE, pour indiquer que la ligne est exclue pour l’opération en bloc.

    • SQL_ROW_PROCEED, pour indiquer que la ligne est incluse dans l’opération en bloc. (Il s'agit de la valeur par défaut.)

  3. Appelez SQLSetPos pour effectuer l’opération en bloc.

Les règles suivantes s’appliquent au tableau d’opérations de ligne :

  • SQL_ROW_IGNORE et SQL_ROW_PROCEED affectent uniquement les opérations en bloc à l’aide de SQLSetPos avec une opération de SQL_DELETE ou de SQL_UPDATE. Ils n’affectent pas les appels à SQLSetPos avec une opération de SQL_REFRESH ou de SQL_POSITION.

  • Le pointeur est défini sur Null par défaut.

  • Si le pointeur a la valeur Null, toutes les lignes sont mises à jour comme si tous les éléments étaient définis sur SQL_ROW_PROCEED.

  • La définition d’un élément sur SQL_ROW_PROCEED ne garantit pas que l’opération se produira sur cette ligne particulière. Par exemple, si une ligne donnée dans l’ensemble de lignes a l’état SQL_ROW_ERROR, le pilote peut ne pas être en mesure de mettre à jour cette ligne, que l’application spécifiée SQL_ROW_PROCEED. Une application doit toujours vérifier le tableau d’état de ligne pour déterminer si l’opération a réussi.

  • SQL_ROW_PROCEED est défini comme 0 dans le fichier d’en-tête. Une application peut initialiser le tableau d’opérations de ligne sur 0 pour traiter toutes les lignes.

  • Si le numéro d’élément « n » dans le tableau d’opérations de ligne est défini sur SQL_ROW_IGNORE et SQLSetPos est appelé pour effectuer une opération de mise à jour ou de suppression en bloc, la nième ligne de l’ensemble de lignes reste inchangée après l’appel à SQLSetPos.

  • Une application doit définir automatiquement une colonne en lecture seule sur SQL_ROW_IGNORE.

Ignorer une colonne dans une opération en bloc

Pour éviter les diagnostics de traitement inutiles générés par une tentative de mise à jour vers une ou plusieurs colonnes en lecture seule, une application peut définir la valeur dans la mémoire tampon de longueur/indicateur liée sur SQL_COLUMN_IGNORE. Pour plus d’informations, consultez SQLBindCol.

Exemple de code

Dans l’exemple suivant, une application permet à un utilisateur de parcourir la table ORDERS et de mettre à jour l’état de l’ordre. Le curseur est piloté par un jeu de clés avec une taille d’ensemble de lignes de 20 et utilise un contrôle d’accès concurrentiel optimiste comparant les versions de lignes. Une fois chaque ensemble de lignes récupéré, l’application l’imprime et permet à l’utilisateur de sélectionner et de mettre à jour l’état d’une commande. L’application utilise SQLSetPos pour positionner le curseur sur la ligne sélectionnée et effectuer une mise à jour positionnée de la ligne. (La gestion des erreurs est omise pour plus de clarté.)

#define ROWS 20  
#define STATUS_LEN 6  
  
SQLCHAR        szStatus[ROWS][STATUS_LEN], szReply[3];  
SQLINTEGER     cbStatus[ROWS], cbOrderID;  
SQLUSMALLINT   rgfRowStatus[ROWS];  
SQLUINTEGER    sOrderID, crow = ROWS, irow;  
SQLHSTMT       hstmtS, hstmtU;  
  
SQLSetStmtAttr(hstmtS, SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0);  
SQLSetStmtAttr(hstmtS, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_KEYSET_DRIVEN, 0);  
SQLSetStmtAttr(hstmtS, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ROWS, 0);  
SQLSetStmtAttr(hstmtS, SQL_ATTR_ROW_STATUS_PTR, (SQLPOINTER) rgfRowStatus, 0);  
SQLSetCursorName(hstmtS, "C1", SQL_NTS);  
SQLExecDirect(hstmtS, "SELECT ORDERID, STATUS FROM ORDERS ", SQL_NTS);  
  
SQLBindCol(hstmtS, 1, SQL_C_ULONG, &sOrderID, 0, &cbOrderID);  
SQLBindCol(hstmtS, 2, SQL_C_CHAR, szStatus, STATUS_LEN, &cbStatus);  
  
while ((retcode == SQLFetchScroll(hstmtS, SQL_FETCH_NEXT, 0)) != SQL_ERROR) {  
   if (retcode == SQL_NO_DATA_FOUND)  
      break;  
   for (irow = 0; irow < crow; irow++) {  
      if (rgfRowStatus[irow] != SQL_ROW_DELETED)  
         printf("%2d %5d %*s\n", irow+1, sOrderID, NAME_LEN-1, szStatus[irow]);  
   }  
   while (TRUE) {  
      printf("\nRow number to update?");  
      gets_s(szReply, 3);  
      irow = atoi(szReply);  
      if (irow > 0 && irow <= crow) {  
         printf("\nNew status?");  
         gets_s(szStatus[irow-1], (ROWS * STATUS_LEN));  
         SQLSetPos(hstmtS, irow, SQL_POSITION, SQL_LOCK_NO_CHANGE);  
         SQLPrepare(hstmtU,  
          "UPDATE ORDERS SET STATUS=? WHERE CURRENT OF C1", SQL_NTS);  
         SQLBindParameter(hstmtU, 1, SQL_PARAM_INPUT,  
            SQL_C_CHAR, SQL_CHAR,  
            STATUS_LEN, 0, szStatus[irow], 0, NULL);  
         SQLExecute(hstmtU);  
      } else if (irow == 0) {  
         break;  
      }  
   }  
}  

Pour plus d’exemples, consultez Instructions de mise à jour et de suppression positionnées et mise à jour des lignes dans l’ensemble de lignes avec SQLSetPos.

Pour plus d’informations sur Consultez
Liaison d’une mémoire tampon à une colonne dans un jeu de résultats SQLBindCol, fonction
Exécution d’opérations en bloc qui ne sont pas liées à la position du curseur de bloc SQLBulkOperations, fonction
Annulation du traitement des instructions SQLCancel, fonction
Extraction d’un bloc de données ou défilement d’un jeu de résultats SQLFetchScroll, fonction
Obtention d’un seul champ d’un descripteur SQLGetDescField, fonction
Obtention de plusieurs champs d’un descripteur SQLGetDescRec, fonction
Définition d’un seul champ d’un descripteur SQLSetDescField, fonction
Définition de plusieurs champs d’un descripteur SQLSetDescRec, fonction
Définition d’un attribut d’instruction SQLSetStmtAttr, fonction

Voir aussi

Informations de référence sur l’API ODBC
Fichiers d’en-tête ODBC