Sdílet prostřednictvím


SQL: Přizpůsobení příkazu SQL sady záznamů (ODBC)

Toto téma vysvětluje:

  • Jak architektura vytváří příkaz SQL

  • Přepsání příkazu SQL

Poznámka:

Tyto informace platí pro třídy MFC ODBC. Pokud pracujete s třídami MFC DAO, přečtěte si téma Porovnání sql databázového stroje Microsoft Jet a ANSI SQL v nápovědě k rozhraní DAO.

Konstrukce příkazů SQL

Sada záznamů zakládá výběr záznamů primárně na příkazu SQL SELECT . Když deklarujete třídu pomocí průvodce, zapíše přepsánou verzi GetDefaultSQL členské funkce, která vypadá nějak takto (pro třídu sady záznamů volanou CAuthors).

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

Ve výchozím nastavení toto přepsání vrátí název tabulky, který jste zadali pomocí průvodce. V příkladu je název tabulky "AUTHORS". Když později zavoláte členskou Open funkci sady záznamů, Open vytvoří konečný příkaz SELECT formuláře:

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

kde table-name je získán voláním GetDefaultSQL a rfx-field-list je získán z volání funkce RFX v DoFieldExchange. Toto je to, co získáte pro příkaz SELECT , pokud ho nenahrazujete přepsáním verze za běhu, i když můžete také upravit výchozí příkaz s parametry nebo filtrem.

Poznámka:

Pokud zadáte název sloupce, který obsahuje (nebo může obsahovat) mezery, musíte název uzavřít do hranatých závorek. Například jméno "Jméno" by mělo být "[Jméno]".

Chcete-li přepsat výchozí příkaz SELECT , předejte řetězec obsahující úplný příkaz SELECT při volání Open. Místo vytvoření vlastního výchozího řetězce používá sada záznamů zadaný řetězec. Pokud příkaz nahrazení obsahuje klauzuli WHERE , nezadávejte filtr m_strFilter , protože byste pak měli dva příkazy filtru. Podobně pokud příkaz nahrazení obsahuje klauzuli ORDER BY , nezadávejte řazení m_strSort tak, abyste neměli dva příkazy řazení.

Poznámka:

Pokud ve filtrech (nebo jiných částech příkazu SQL) používáte literály, možná budete muset takové řetězce s předponou literálu specifickou pro DBMS a znakem literálové přípony (nebo znaků) obsahovat "uvozovky" (uzavřené do zadaných oddělovačů).

V závislosti na databázi DBMS můžete také narazit na zvláštní syntaktické požadavky na operace, jako jsou vnější spojení. Pomocí funkcí ODBC získejte tyto informace z ovladače pro DBMS. Například volání ::SQLGetTypeInfo konkrétního datového typu, například SQL_VARCHAR, požadovat LITERAL_PREFIX a LITERAL_SUFFIX znaky. Pokud píšete kód nezávislý na databázi, přečtěte si článek C: Gramatika SQL v referenční dokumentaci programátora ODBC s podrobnými informacemi o syntaxi.

Objekt sady záznamů vytvoří příkaz SQL, který používá k výběru záznamů, pokud předáte vlastní příkaz SQL. Způsob provedení závisí hlavně na hodnotě, kterou předáte parametru Open lpszSQL členské funkce.

Obecná forma příkazu SQL SELECT je:

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

Jedním ze způsobů, jak přidat klíčové slovo DISTINCT do příkazu SQL sady záznamů, je vložit klíčové slovo do prvního volání funkce RFX do DoFieldExchange. Příklad:

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

Poznámka:

Tuto techniku použijte pouze se sadou záznamů otevřenou jen pro čtení.

Přepsání příkazu SQL

Následující tabulka ukazuje možnosti parametru lpszSQL na Open. Případy v tabulce jsou vysvětleny podle tabulky.

Parametr lpszSQL a výsledný řetězec SQL

Velikost písmen Co předáváte v lpszSQL Výsledný příkaz SELECT
0 NULL SELECT rfx-field-list FROM table-name

CRecordset::Open volání GetDefaultSQL pro získání názvu tabulky. Výsledný řetězec je jedním z případů 2 až 5 v závislosti na tom, co GetDefaultSQL se vrátí.
2 Název tabulky SELECT rfx-field-list FROM table-name

Seznam polí je převzat z příkazů RFX v DoFieldExchange. Pokud m_strFilter a m_strSort nejsou prázdné, přidá klauzule WHERE a/nebo ORDER BY .
3* Kompletní příkaz SELECT, ale bez klauzule WHERE nebo ORDER BY Jak bylo předáno. Pokud m_strFilter a m_strSort nejsou prázdné, přidá klauzule WHERE a/nebo ORDER BY .
4 * Kompletní příkaz SELECT s klauzulí WHERE a/nebo ORDER BY Jak bylo předáno. m_strFilter a/nebo m_strSort musí zůstat prázdné, nebo se vytvoří dva příkazy filtru nebo řazení.
5 * Volání uložené procedury Jak bylo předáno.

* m_nFields musí být menší nebo roven počtu sloupců zadaných v příkazu SELECT . Datový typ každého sloupce zadaného v příkazu SELECT musí být stejný jako datový typ odpovídajícího výstupního sloupce RFX.

Případ 1 lpszSQL = NULL

Výběr sady záznamů závisí na tom, co GetDefaultSQL se vrátí při CRecordset::Open volání. Případy 2 až 5 popisují možné řetězce.

Případ 2 lpszSQL = název tabulky

Sada záznamů používá výměnu polí záznamu (RFX) k sestavení seznamu sloupců z názvů sloupců uvedených ve volání funkce RFX v přepsání DoFieldExchangetřídy záznamů . Pokud jste použili průvodce k deklaraci třídy sady záznamů, má tento případ stejný výsledek jako případ 1 (za předpokladu, že předáte stejný název tabulky, který jste zadali v průvodci). Pokud k zápisu třídy nepoužíváte průvodce, případ 2 je nejjednodušší způsob, jak sestavit příkaz SQL.

Následující příklad vytvoří příkaz SQL, který vybere záznamy z databázové aplikace MFC. Při volání GetDefaultSQL členské funkce rozhraní vrátí funkce název tabulky, SECTION.

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

Chcete-li získat názvy sloupců pro příkaz SQL SELECT , architektura volá DoFieldExchange členské funkce.

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);
}

Po dokončení vypadá příkaz SQL takto:

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

Case 3 lpszSQL = příkaz SELECT/FROM

Seznam sloupců zadáte ručně, místo abyste se museli spoléhat na RFX, aby se sestavil automaticky. Můžete to udělat v těchto případech:

  • Chcete zadat klíčové slovo DISTINCT podle příkazu SELECT.

    Seznam sloupců by měl odpovídat názvům a typům sloupců ve stejném pořadí, v jakém jsou uvedeny .DoFieldExchange

  • Máte důvod ručně načíst hodnoty sloupců pomocí funkce ::SQLGetData ODBC místo toho, abyste se spoléhali na RFX, aby se svážely a načítaly sloupce za vás.

    Můžete například chtít pojmout nové sloupce, které zákazník vaší aplikace přidal do databázových tabulek po distribuci aplikace. Tyto další datové členy pole je třeba přidat, které nebyly známy v době, kdy jste deklarovali třídu pomocí průvodce.

    Seznam sloupců by se měl shodovat s názvy a typy sloupců ve stejném pořadí, v jakém jsou uvedeny DoFieldExchange, a za nimi názvy ručně vázaných sloupců. Další informace naleznete v tématu Sada záznamů: Dynamické vazby datových sloupců (ODBC).

  • Tabulky chcete spojit zadáním více tabulek v klauzuli FROM .

    Informace a příklad naleznete v tématu Sada záznamů: Provedení spojení (ODBC).

Případ 4 lpszSQL = SELECT/FROM Plus WHERE a/nebo ORDER BY

Zadáte vše: seznam sloupců (na základě volání RFX v DoFieldExchange), seznam tabulek a obsah klauzule WHERE a/nebo ORDER BY . Pokud tímto způsobem zadáte klauzule WHERE a/nebo ORDER BY, nepoužívejte am_strFilter/nebo m_strSort.

Case 5 lpszSQL = volání uložené procedury

Pokud potřebujete volat předdefinovaný dotaz (například uloženou proceduru v databázi Microsoft SQL Serveru), musíte do řetězce, který předáte lpszSQL, napsat příkaz CALL. Průvodci nepodporují deklaraci třídy sady záznamů pro volání předdefinovaného dotazu. Ne všechny předdefinované dotazy vrací záznamy.

Pokud předdefinovaný dotaz nevrací záznamy, můžete členské funkce ExecuteSQL použít CDatabase přímo. U předdefinovaného dotazu, který vrací záznamy, musíte také ručně zapsat volání DoFieldExchange RFX pro všechny sloupce, které procedura vrátí. Volání RFX musí být ve stejném pořadí a vrátit stejné typy jako předdefinovaný dotaz. Další informace naleznete v tématu Sada záznamů: Deklarování třídy pro předdefinovaný dotaz (ODBC).

Viz také

SQL: Datové typy SQL a C++ (ODBC)
SQL: Přímá volání SQL (ODBC)