SQL: dostosowywanie instrukcji SQL zestawu rekordów (ODBC)

W tym temacie opisano:

  • Jak struktura konstruuje instrukcję SQL

  • Jak zastąpić instrukcję SQL

Uwaga

Te informacje dotyczą klas MFC ODBC. Jeśli pracujesz z klasami MFC DAO, zobacz temat "Porównanie bazy danych Microsoft Jet Database Engine SQL i ANSI SQL" w pomocy dao.

Konstrukcja instrukcji SQL

Zestaw rekordów opiera wybór rekordów głównie na instrukcji SQL SELECT . Podczas deklarowania klasy za pomocą kreatora zapisuje on zastępowającą wersję GetDefaultSQL funkcji składowej, która wygląda mniej więcej tak (w przypadku klasy zestawu rekordów o nazwie CAuthors).

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

Domyślnie to zastąpienie zwraca nazwę tabeli określoną za pomocą kreatora. W tym przykładzie nazwa tabeli to "AUTORZY". Po późniejszym wywołaniu funkcji Open składowej Open zestawu rekordów tworzy ostateczną instrukcję SELECT formularza:

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

gdzie table-name jest uzyskiwany przez wywołanie GetDefaultSQL i rfx-field-list jest uzyskiwany z wywołań funkcji RFX w .DoFieldExchange Jest to, co otrzymujesz dla instrukcji SELECT , chyba że zastąpisz ją przesłoniętą wersją w czasie wykonywania, chociaż można również zmodyfikować domyślną instrukcję za pomocą parametrów lub filtru.

Uwaga

Jeśli określisz nazwę kolumny, która zawiera (lub może zawierać) spacje, musisz ująć nazwę w nawiasy kwadratowe. Na przykład nazwa "Imię" powinna mieć wartość "[Imię]".

Aby zastąpić domyślną instrukcję SELECT , przekaż ciąg zawierający pełną instrukcję SELECT podczas wywoływania metody Open. Zamiast konstruować własny ciąg domyślny, zestaw rekordów używa dostarczanego ciągu. Jeśli instrukcja zastępcza zawiera klauzulę WHERE , nie należy określać filtru, m_strFilter ponieważ wówczas istnieją dwie instrukcje filtru. Podobnie, jeśli instrukcja zastępcza zawiera klauzulę ORDER BY , nie należy określać sortowania, m_strSort aby nie mieć dwóch instrukcji sortowania.

Uwaga

Jeśli używasz ciągów literału w filtrach (lub innych części instrukcji SQL), może być konieczne "cudzysłów" (ujęte w określone ograniczniki), takie ciągi z prefiksem literału specyficznym dla systemu DBMS i znakiem sufiksu literału (lub znakami).

Mogą również wystąpić specjalne wymagania składniowe dotyczące operacji, takich jak sprzężenia zewnętrzne, w zależności od systemu DBMS. Użyj funkcji ODBC, aby uzyskać te informacje ze sterownika dla systemu DBMS. Na przykład wywołanie ::SQLGetTypeInfo określonego typu danych, takiego jak SQL_VARCHAR, w celu żądania LITERAL_PREFIX i LITERAL_SUFFIX znaków. Jeśli piszesz kod niezależny od bazy danych, zobacz Dodatek C: Gramatyka SQL w dokumentacji programisty ODBC, aby uzyskać szczegółowe informacje o składni.

Obiekt zestawu rekordów konstruuje instrukcję SQL używaną do wybierania rekordów, chyba że zostanie przekazana niestandardowa instrukcja SQL. Sposób wykonania tej czynności zależy głównie od wartości przekazywanej w parametrze lpszSQL funkcji składowej Open .

Ogólna forma instrukcji SQL SELECT to:

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

Jednym ze sposobów dodania słowa kluczowego DISTINCT do instrukcji SQL zestawu rekordów jest osadzanie słowa kluczowego w pierwszym wywołaniu funkcji RFX w pliku DoFieldExchange. Na przykład:

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

Uwaga

Ta technika jest używana tylko w przypadku zestawu rekordów otwartego jako tylko do odczytu.

Zastępowanie instrukcji SQL

W poniższej tabeli przedstawiono możliwości parametru lpszSQL do Open. Przypadki w tabeli zostały wyjaśnione w poniższej tabeli.

Parametr lpszSQL i wynikowy ciąg SQL

Przypadek Co przekazujesz w narzędziu lpszSQL Wynikowa instrukcja SELECT
1 NULL SELECTrfx-field-listFROMtable-name

CRecordset::Open wywołania GetDefaultSQL w celu pobrania nazwy tabeli. Wynikowy ciąg jest jednym z przypadków od 2 do 5 w zależności od GetDefaultSQL zwracanych wartości.
2 Nazwa tabeli SELECTrfx-field-listFROMtable-name

Lista pól jest pobierana z instrukcji RFX w pliku DoFieldExchange. Jeśli m_strFilter i m_strSort nie są puste, dodaje klauzule WHERE i/lub ORDER BY .
3* Kompletna instrukcja SELECT, ale bez klauzuli WHERE lub ORDER BY Zgodnie z przekazaniem. Jeśli m_strFilter i m_strSort nie są puste, dodaje klauzule WHERE i/lub ORDER BY .
4 * Pełna instrukcja SELECT z klauzulą WHERE i/lub ORDER BY Zgodnie z przekazaniem. m_strFilter i/lub m_strSort muszą pozostać puste lub są tworzone dwie instrukcje filtrowania i/lub sortowania.
5 * Wywołanie procedury składowanej Zgodnie z przekazaniem.

* m_nFields musi być mniejsza lub równa liczbie kolumn określonych w instrukcji SELECT . Typ danych każdej kolumny określonej w instrukcji SELECT musi być taki sam jak typ danych odpowiadającej kolumnie wyjściowej RFX.

Przypadek 1 lpszSQL = NULL

Wybór zestawu rekordów zależy od tego, co GetDefaultSQL zwraca w przypadku CRecordset::Open wywołań. Przypadki od 2 do 5 opisują możliwe ciągi.

Przypadek 2 lpszSQL = nazwa tabeli

Zestaw rekordów używa wymiany pól rekordów (RFX) do skompilowania listy kolumn z nazw kolumn podanych w wywołaniach funkcji RFX w zastąpieniu klasy rekordów DoFieldExchange. Jeśli użyto kreatora do zadeklarowania klasy zestawu rekordów, ten przypadek ma taki sam wynik jak przypadek 1 (pod warunkiem, że przekazano tę samą nazwę tabeli określoną w kreatorze). Jeśli nie używasz kreatora do pisania klasy, przypadek 2 jest najprostszym sposobem konstruowania instrukcji SQL.

Poniższy przykład tworzy instrukcję SQL, która wybiera rekordy z aplikacji bazy danych MFC. Gdy struktura wywołuje GetDefaultSQL funkcję składową, funkcja zwraca nazwę tabeli . SECTION

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

Aby uzyskać nazwy kolumn instrukcji SQL SELECT , struktura wywołuje funkcję składową 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 zakończeniu instrukcja SQL wygląda następująco:

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

Case 3 lpszSQL = instrukcja SELECT/FROM

Listę kolumn można określić ręcznie, a nie polegać na RFX, aby utworzyć ją automatycznie. Możesz to zrobić, gdy:

  • Chcesz określić słowo kluczowe DISTINCT zgodnie z instrukcją SELECT.

    Lista kolumn powinna być zgodna z nazwami i typami kolumn w takiej samej kolejności, jak na liście .DoFieldExchange

  • Masz powód, aby ręcznie pobrać wartości kolumn przy użyciu funkcji ::SQLGetData ODBC, a nie polegać na RFX, aby powiązać i pobrać kolumny.

    Możesz na przykład chcieć pomieścić nowe kolumny, które klient aplikacji dodał do tabel bazy danych po rozproszeniu aplikacji. Należy dodać te dodatkowe składowe danych pól, które nie były znane w momencie zadeklarowania klasy za pomocą kreatora.

    Lista kolumn powinna być zgodna z nazwami i typami kolumn w tej samej kolejności, w której znajdują się na liście DoFieldExchange, a następnie nazwy ręcznie powiązanych kolumn. Aby uzyskać więcej informacji, zobacz Zestaw rekordów: dynamiczne wiązanie kolumn danych (ODBC).

  • Tabele chcesz sprzężć, określając wiele tabel w klauzuli FROM .

    Aby uzyskać informacje i przykład, zobacz Zestaw rekordów: wykonywanie sprzężenia (ODBC).

Przypadek 4 lpszSQL = SELECT/FROM Plus WHERE i/lub ORDER BY

Określasz wszystko: listę kolumn (na podstawie wywołań RFX w programie DoFieldExchange), listę tabel oraz zawartość klauzuli WHERE i/lub KLAUZULi ORDER BY . Jeśli określisz klauzule WHERE i/lub ORDER BY w ten sposób, nie używaj m_strFilter i/lub m_strSort.

Przypadek 5 lpszSQL = wywołanie procedury składowanej

Jeśli musisz wywołać wstępnie zdefiniowane zapytanie (takie jak procedura składowana w bazie danych programu Microsoft SQL Server), musisz napisać instrukcję CALL w ciągu przekazywanym do lpszSQL. Kreatory nie obsługują deklarowania klasy zestawu rekordów do wywoływania wstępnie zdefiniowanego zapytania. Nie wszystkie wstępnie zdefiniowane zapytania zwracają rekordy.

Jeśli wstępnie zdefiniowane zapytanie nie zwraca rekordów, możesz użyć funkcji ExecuteSQL składowej CDatabase bezpośrednio. W przypadku wstępnie zdefiniowanego zapytania, które zwraca rekordy, należy również ręcznie napisać wywołania RFX dla DoFieldExchange wszystkich kolumn zwracanych przez procedurę. Wywołania RFX muszą być w tej samej kolejności i zwracać te same typy, co wstępnie zdefiniowane zapytanie. Aby uzyskać więcej informacji, zobacz Zestaw rekordów: deklarowanie klasy dla wstępnie zdefiniowanego zapytania (ODBC).

Zobacz też

SQL: typy danych SQL i C++ (ODBC)
SQL: wykonywanie bezpośrednich wywołań SQL (ODBC)