Sdílet prostřednictvím


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

Toto téma vysvětluje:

  • Jak architektura sestavuje příkaz SQL

  • Jak přepsat příkaz SQL

[!POZNÁMKA]

Tyto informace platí pro třídy knihovny MFC rozhraní ODBC.Pokud pracujete se třídami knihovny MFC rozhraní DAO, prohlédněte si "Comparison of Microsoft Jet Database Engine SQL and ANSI SQL" v nápovědě rozhraní DAO.

Konstrukce příkazu SQL

Vaše sada záznamů zakládá výběr záznamů především na příkazech SQL SELECT.Když deklarujete vaši třídu pomocí průvodce, zapíše přepisující verzi členské funkce GetDefaultSQL, která vypadá nějak takto (pro třídu sady záznamů s názvem CAuthors).

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

Ve výchozím nastavení toto přepsání vrací název tabulky, který jste zadali pomocí průvodce.V příkladu je název tabulky "AUTHORS." Pokud později zavoláte členskou funkci Open sady záznamů, Open sestaví finální příkaz SELECT podobně jako:

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

kde table-name je získáno voláním GetDefaultSQL a rfx-field-list je získáno z volání funkce RFX v DoFieldExchange.Toto získáte pro příkaz SELECT, pokud jej za běhu nenahradíte přepisující verzí, přestože můžete také změnit výchozí příkaz pomocí parametrů nebo filtru.

[!POZNÁMKA]

Pokud zadáte název sloupce, který obsahuje (nebo by mohl obsahovat) mezery, je nutné uzavřít název do hranatých závorek.Například název "First Name" by měl být "[First Name]".

Pro přepsání výchozího příkazu SELECT předejte řetězec, obsahující úplný příkaz SELECT při volání Open.Namísto vytváření vlastního výchozího řetězce použije sada záznamů řetězec, který poskytnete.Pokud váš nahrazující příkaz obsahuje klauzuli WHERE, nezadávejte filtr v m_strFilter, protože pak byste měli dva filtrační příkazy.Podobně pokud váš nahrazující příkaz obsahuje klauzuli ORDER BY, neurčujte řazení v m_strSort, abyste neměli dva řadící příkazy.

[!POZNÁMKA]

Pokud použijete ve vašich filtrech (nebo v jiných částech příkazu SQL) řetězcové literály, pravděpodobně budete muset "citovat" (uzavřít do zadaných oddělovačů) tyto řetězce znaky pro literál předpony a literál přípony, specifickými pro DBMS.

Měli byste také počítat se zvláštními syntaktickými požadavky pro operace, jako jsou vnější spojení, v závislosti na systému DBMS.Použijte funkce rozhraní ODBC pro získání těchto informací od vašeho ovladače pro DBMS.Například volejte ::SQLGetTypeInfo pro konkrétní datový typ, jako je SQL_VARCHAR, pro požadování znaků LITERAL_PREFIX a LITERAL_SUFFIX.Pokud vytváříte kód nezávislý na databázi, prohlédněte si dodatek C ODBC SDKProgrammer's Reference na disku CD knihovny MSDN pro podrobné informace o syntaxi.

Objekt sady záznamů vytváří příkaz SQL, který používá k výběru záznamů, pokud nepředáte vlastní příkaz SQL.Jak je toto provedeno závisí hlavně na hodnotě, kterou předáte v parametru lpszSQL členské funkce Open.

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 vaší sady záznamů, je vložit klíčové slovo do prvního volání funkce RFX v DoFieldExchange.Příklad:

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

[!POZNÁMKA]

Tento postup použijte pouze u sady záznamů, otevřené jen pro čtení.

Přepsání příkazu SQL

V následující tabulce jsou uvedeny možnosti pro parametr lpszSQL pro Open.Případy v tabulce jsou vysvětleny následováním tabulky.

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

Pevný obal

Co předáte v lpszSQL

Výsledný příkaz SELECT

1

NULL

SELECTrfx-field-listFROMtable-name

CRecordset::Open volá GetDefaultSQL pro získání názvu tabulky.Výsledný řetězec je jedním z případů 2 až 5, podle toho, co vrátí GetDefaultSQL.

2

Název tabulky

SELECTrfx-field-listFROMtable-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

Tak jak je předán.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

Tak jak je předán.m_strFilter a/nebo m_strSort musí zůstat prázdné nebo budou vytvořeny dva filtry a/nebo příkazy řazení.

5 *

Volání uložené procedury.

Tak jak je předán.

* m_nFields musí být menší než počet sloupců zadaných v Vybrat prohlášení.Datový typ každého sloupce, určené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 vrátí GetDefaultSQL při volání prostřednictvím CRecordset::Open.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 pole záznamu (RFX) pro sestavení seznamu sloupců z názvů sloupců, poskytnutých ve voláních funkce RFX v přepsání DoFieldExchange třídy sady záznamů.Pokud jste použili průvodce pro deklarování vaší 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 nepoužijete průvodce pro napsání vaší třídy, případ 2 představuje nejjednodušší způsob vytvoření příkazu SQL.

Následující příklad vytvoří příkaz SQL, který vybere záznamy z databázové aplikace MFC.Když architektura volá členskou funkci GetDefaultSQL, vrátí funkce název tabulky, SECTION.

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

Pro získání názvů sloupců pro příkaz SQL SELECT volá architektura členskou funkci DoFieldExchange.

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

Případ 3   lpszSQL = Příkaz SELECT/FROM

Určíte seznam sloupců ručně, bez spoléhání na automatické vytvoření pomocí RFX.Můžete toto chtít provést, když:

  • Chcete zadat klíčové slovo DISTINCT po SELECT.

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

  • Máte důvod pro ruční načtení hodnot sloupců pomocí funkce rozhraní ODBC ::SQLGetData namísto spoléhání na to, že RFX sváže a načte sloupce za vás.

    Můžete například chtít umístit nové sloupce, které přidal zákazník vaší aplikace do databázových tabulek poté, co byla aplikace distribuována.Potřebujete přidat tyto dodatečné datové členy položek, které nebyly známy v době, kdy jste deklarovali třídu pomocí průvodce.

    Váš seznam sloupců by měl odpovídat názvům a typům sloupců ve stejném pořadí, v jakém jsou uvedeny v DoFieldExchange, následovaný názvy ručně vázaných sloupců.Další informace naleznete v tématu Sada záznamů: Dynamické vazby datových sloupců (ODBC).

  • Chcete spojit tabulky zadáním více tabulek v klauzuli FROM.

    Pro informace a příklad si prohlédněte Sada záznamů: Provedení spojení (rozhraní ODBC).

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

Zadáte vše: seznam sloupců (založený na volání RFX v DoFieldExchange), seznam tabulek a obsah kde nebo ORDER klauzule.Pokud zadáte vaše klauzule WHERE a/nebo ORDER BY tímto způsobem, nepoužívejte m_strFilter a/nebo m_strSort.

Případ 5   lpszSQL = volání uložené procedury

Potřebujete-li volat předdefinovaný dotaz (například uloženou proceduru v databázi Microsoft SQL Server), musíte napsat příkaz CALL v řetězci, který předáte lpszSQL.Průvodci nepodporují deklarování 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 použít členskou funkci CDatabaseExecuteSQL přímo.Pro předdefinovaný dotaz vracející záznamy musíte také ručně napsat volání RFX v DoFieldExchange pro všechny sloupce, které procedura vrací.Volání RFX musí být ve stejném pořadí a vracet 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é

Koncepty

SQL: SQL a datové typy C++ (ODBC)

SQL: Přímá volání SQL (ODBC)