Partager via


SQL : Personnalisation de l’instruction SQL de votre recordset (ODBC)

Cette rubrique explique :

  • Comment l’infrastructure construit une instruction SQL

  • Comment remplacer l’instruction SQL

Remarque

Ces informations s’appliquent aux classes ODBC MFC. Si vous travaillez avec les classes DAO MFC, consultez la rubrique « Comparaison de Microsoft Jet Moteur de base de données SQL et ANSI SQL » dans l’aide DAO.

Construction d’instructions SQL

Votre jeu d’enregistrements base principalement la sélection d’enregistrements sur une instruction SQL SELECT . Lorsque vous déclarez votre classe avec un Assistant, elle écrit une version substituante de la GetDefaultSQL fonction membre qui ressemble à ceci (pour une classe recordset appelée CAuthors).

CString CAuthors::GetDefaultSQL()
{
    return "AUTHORS";
}

Par défaut, cette substitution retourne le nom de table que vous avez spécifié avec l’Assistant. Dans l’exemple, le nom de la table est « AUTHORS ». Lorsque vous appelez ultérieurement la fonction membre du Open jeu d’enregistrements, Open construit une instruction SELECT finale du formulaire :

SELECT rfx-field-list FROM table-name [WHERE m_strFilter]
       [ORDER BY m_strSort]

table-name est obtenu en appelant GetDefaultSQL et rfx-field-list obtenu à partir des appels de fonction RFX dans DoFieldExchange. Il s’agit de ce que vous obtenez pour une instruction SELECT , sauf si vous la remplacez par une version substituée au moment de l’exécution, bien que vous puissiez également modifier l’instruction par défaut par des paramètres ou un filtre.

Remarque

Si vous spécifiez un nom de colonne qui contient (ou peut contenir) des espaces, vous devez placer le nom entre crochets. Par exemple, le nom « Prénom » doit être « [Prénom] ».

Pour remplacer l’instruction SELECT par défaut, passez une chaîne contenant une instruction SELECT complète lorsque vous appelez Open. Au lieu de construire sa propre chaîne par défaut, le jeu d’enregistrements utilise la chaîne que vous fournissez. Si votre instruction de remplacement contient une clause WHERE , ne spécifiez pas de filtre, m_strFilter car vous auriez alors deux instructions de filtre. De même, si votre instruction de remplacement contient une clause ORDER BY , ne spécifiez pas de tri m_strSort afin que vous n’ayez pas deux instructions de tri.

Remarque

Si vous utilisez des chaînes littérales dans vos filtres (ou d’autres parties de l’instruction SQL), vous devrez peut-être « citer » (placer dans des délimiteurs spécifiés) ces chaînes avec un préfixe littéral spécifique au SGBD et un caractère de suffixe littéral (ou caractères).

Vous pouvez également rencontrer des exigences syntactiques spéciales pour les opérations telles que les jointures externes, en fonction de votre SGBD. Utilisez des fonctions ODBC pour obtenir ces informations auprès de votre pilote pour le SGBD. Par exemple, appelez ::SQLGetTypeInfo un type de données particulier, tel que SQL_VARCHAR, pour demander les LITERAL_PREFIX et les caractères LITERAL_SUFFIX. Si vous écrivez du code indépendant de la base de données, consultez l’annexe C : Grammaire SQL dans la référence du programmeur ODBC pour obtenir des informations détaillées sur la syntaxe.

Un objet recordset construit l’instruction SQL qu’il utilise pour sélectionner des enregistrements, sauf si vous passez une instruction SQL personnalisée. La façon dont cela est fait dépend principalement de la valeur que vous passez dans le paramètre lpszSQL de la Open fonction membre.

La forme générale d’une instruction SQL SELECT est la suivante :

SELECT [ALL | DISTINCT] column-list FROM table-list
    [WHERE search-condition][ORDER BY column-list [ASC | DESC]]

Une façon d’ajouter la mot clé DISTINCT à l’instruction SQL de votre jeu d’enregistrements consiste à incorporer le mot clé dans le premier appel de fonction RFX dans DoFieldExchange. Par exemple :

...
    RFX_Text(pFX, "DISTINCT CourseID", m_strCourseID);
...

Remarque

Utilisez cette technique uniquement avec un jeu d’enregistrements ouvert en lecture seule.

Substitution de l’instruction SQL

Le tableau suivant présente les possibilités pour le paramètre lpszSQL à Open. Les cas du tableau sont expliqués en suivant le tableau.

Paramètre lpszSQL et chaîne SQL résultante

Incident Ce que vous passez dans lpszSQL Instruction SELECT résultante
1 NULL SELECTrfx-field-listFROMtable-name

CRecordset::Open appels GetDefaultSQL pour obtenir le nom de la table. La chaîne résultante est l’un des cas 2 à 5, en fonction de ce qui GetDefaultSQL retourne.
2 Nom d’une table SELECTrfx-field-listFROMtable-name

La liste de champs est extraite des instructions RFX dans DoFieldExchange. Si m_strFilter et m_strSort ne sont pas vides, ajoute les clauses WHERE et/ou ORDER BY .
3* Instruction SELECT complète, mais sans clause WHERE ou ORDER BY Tel qu’il a été passé. Si m_strFilter et m_strSort ne sont pas vides, ajoute les clauses WHERE et/ou ORDER BY .
4* Instruction SELECT complète avec une clause WHERE et/ou ORDER BY Tel qu’il a été passé. m_strFilter et/ou m_strSort doit rester vide, ou deux instructions de filtre et/ou de tri sont produites.
5 * Un appel à une procédure stockée Tel qu’il a été passé.

* m_nFields doit être inférieur ou égal au nombre de colonnes spécifiées dans l’instruction SELECT . Le type de données de chaque colonne spécifiée dans l’instruction SELECT doit être identique au type de données de la colonne de sortie RFX correspondante.

Cas 1 lpszSQL = NULL

La sélection du jeu d’enregistrements dépend de ce qui GetDefaultSQL retourne lors CRecordset::Open de son appel. Les cas 2 à 5 décrivent les chaînes possibles.

Cas 2 lpszSQL = un nom de table

Le jeu d’enregistrements utilise l’échange de champs d’enregistrement (RFX) pour générer la liste des colonnes à partir des noms de colonnes fournis dans les appels de fonction RFX dans le remplacement de DoFieldExchangela classe recordset . Si vous avez utilisé un Assistant pour déclarer votre classe recordset, ce cas a le même résultat que le cas 1 (à condition que vous transmettiez le même nom de table que celui que vous avez spécifié dans l’Assistant). Si vous n’utilisez pas d’Assistant pour écrire votre classe, le cas 2 est le moyen le plus simple de construire l’instruction SQL.

L’exemple suivant construit une instruction SQL qui sélectionne les enregistrements d’une application de base de données MFC. Lorsque l’infrastructure appelle la GetDefaultSQL fonction membre, la fonction retourne le nom de la table. SECTION

CString CEnrollSet::GetDefaultSQL()
{
    return "SECTION";
}

Pour obtenir les noms des colonnes de l’instruction SQL SELECT , l’infrastructure appelle la DoFieldExchange fonction membre.

void CEnrollSet::DoFieldExchange(CFieldExchange* pFX)
{
    pFX->SetFieldType(CFieldExchange::outputColumn);
    RFX_Text(pFX, "CourseID", m_strCourseID);
    RFX_Text(pFX, "InstructorID", m_strInstructorID);
    RFX_Text(pFX, "RoomNo", m_strRoomNo);
    RFX_Text(pFX, "Schedule", m_strSchedule);
    RFX_Text(pFX, "SectionNo", m_strSectionNo);
}

Une fois terminée, l’instruction SQL ressemble à ceci :

SELECT CourseID, InstructorID, RoomNo, Schedule, SectionNo
    FROM SECTION

Cas 3 lpszSQL = instruction SELECT/FROM

Vous spécifiez la liste de colonnes à la main plutôt que de vous appuyer sur RFX pour la construire automatiquement. Vous pouvez le faire lorsque :

  • Vous souhaitez spécifier le mot clé DISTINCT suivant SELECT.

    Votre liste de colonnes doit correspondre aux noms et types de colonnes dans le même ordre qu’ils sont répertoriés dans DoFieldExchange.

  • Vous avez la raison de récupérer manuellement des valeurs de colonne à l’aide de la fonction ::SQLGetData ODBC plutôt que de vous appuyer sur RFX pour lier et récupérer des colonnes pour vous.

    Par exemple, vous souhaiterez peut-être prendre en charge de nouvelles colonnes ajoutées par un client de votre application aux tables de base de données après la distribution de l’application. Vous devez ajouter ces membres de données de champ supplémentaires, qui n’étaient pas connus au moment où vous avez déclaré la classe avec un Assistant.

    Votre liste de colonnes doit correspondre aux noms et types de colonnes dans le même ordre qu’ils sont répertoriés, DoFieldExchangesuivis des noms des colonnes liées manuellement. Pour plus d’informations, consultez Recordset : Liaison dynamique de colonnes de données (ODBC)

  • Vous souhaitez joindre des tables en spécifiant plusieurs tables dans la clause FROM .

    Pour plus d’informations et un exemple, consultez Recordset : Exécution d’une jointure (ODBC)

Cas 4 lpszSQL = SELECT/FROM Plus WHERE et/ou ORDER BY

Vous spécifiez tout : la liste de colonnes (basée sur les appels RFX dans DoFieldExchange), la liste de tables et le contenu d’une clause WHERE et/ou ORDER BY . Si vous spécifiez vos clauses WHERE et/ou ORDER BY de cette façon, n’utilisez m_strFilter pas et/ou m_strSort.

Cas 5 lpszSQL = un appel de procédure stockée

Si vous devez appeler une requête prédéfinie (par exemple, une procédure stockée dans une base de données Microsoft SQL Server), vous devez écrire une instruction CALL dans la chaîne que vous passez à lpszSQL. Les Assistants ne prennent pas en charge la déclaration d’une classe recordset pour appeler une requête prédéfinie. Toutes les requêtes prédéfinies ne retournent pas d’enregistrements.

Si une requête prédéfinie ne retourne pas d’enregistrements, vous pouvez utiliser directement la CDatabase fonction ExecuteSQL membre. Pour une requête prédéfinie qui retourne des enregistrements, vous devez également écrire manuellement les appels DoFieldExchange RFX pour toutes les colonnes retournées par la procédure. Les appels RFX doivent être dans le même ordre et retourner les mêmes types que la requête prédéfinie. Pour plus d’informations, consultez Recordset : Déclaration d’une classe pour une requête prédéfinie (ODBC).

Voir aussi

SQL : types de données SQL et C++ (ODBC)
SQL : appels SQL directs (ODBC)