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 | SELECT rfx-field-list FROM table-nameCRecordset::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 | SELECT rfx-field-list FROM table-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)