Udostępnij za pośrednictwem


TN045: obsługa MFC/bazy danych pod względem typu danych Varchar/Varbinary

Uwaga

Następująca uwaga techniczna nie została zaktualizowana, ponieważ została po raz pierwszy uwzględniona w dokumentacji online. W związku z tym niektóre procedury i tematy mogą być nieaktualne lub nieprawidłowe. Aby uzyskać najnowsze informacje, zaleca się wyszukanie interesującego tematu w indeksie dokumentacji online.

W tej notatce opisano sposób pobierania i wysyłania SQL_LONGVARCHAR odBC oraz SQL_LONGVARBINARY typów danych przy użyciu klas baz danych MFC.

Omówienie obsługi long varchar/Varbinary

Typy danych ODBC SQL_LONG_VARCHAR i SQL_LONGBINARY (nazywane tutaj tak długimi kolumnami danych) mogą przechowywać ogromne ilości danych. Istnieją 3 sposoby obsługi tych danych:

  • Powiąż go z elementem CString/CByteArray.

  • Powiąż go z elementem CLongBinary.

  • Nie powiąż jej w ogóle i nie pobieraj i wysyłaj ręcznie długiej wartości danych niezależnie od klas baz danych.

Każda z trzech metod ma zalety i wady.

Długie kolumny danych nie są obsługiwane w przypadku parametrów zapytania. Są one obsługiwane tylko w przypadku kolumn wyjściowych.

Wiązanie długiej kolumny danych z CString/CByteArray

Zalety:

To podejście jest proste do zrozumienia i pracujesz ze znanymi klasami. Platforma zapewnia CFormView obsługę programu CString DDX_Text. Masz wiele ogólnych funkcji ciągów lub kolekcji z klasami CString i CByteArray i i i możesz kontrolować ilość pamięci przydzielonej lokalnie do przechowywania wartości danych. Struktura utrzymuje starą kopię danych pól podczas Edit wywołań funkcji lub AddNew , a platforma może automatycznie wykrywać zmiany danych.

Uwaga

Ponieważ CString jest przeznaczony do pracy z danymi znaków i CByteArray do pracy z danymi binarnymi, zaleca się umieszczenie danych znaków (SQL_LONGVARCHAR) w CStringsystem i danych binarnych (SQL_LONGVARBINARY) w programie CByteArray.

Funkcje RFX dla CString i CByteArray mają dodatkowy argument, który umożliwia zastąpienie domyślnego rozmiaru przydzielonej pamięci do przechowywania pobranej wartości dla kolumny danych. Zwróć uwagę na argument nMaxLength w następujących deklaracjach funkcji:

void AFXAPI RFX_Text(CFieldExchange* pFX,
    const char *szName,
    CString& value,
    int nMaxLength = 255,
    int nColumnType =
    SQL_VARCHAR);

void AFXAPI RFX_Binary(CFieldExchange* pFX,
    const char *szName,
    CByteArray& value,
    int nMaxLength = 255);

W przypadku pobrania długiej kolumny danych do obiektu CString lub CByteArraymaksymalna zwracana ilość danych to domyślnie 255 bajtów. Wszystko poza tym jest ignorowane. W takim przypadku struktura zgłosi wyjątek AFX_SQL_ERROR_DATA_TRUNCATED. Na szczęście można jawnie zwiększyć nMaxLength na większe wartości, maksymalnie MAXINT.

Uwaga

Wartość nMaxLength jest używana przez MFC do ustawiania lokalnego buforu SQLBindColumn funkcji. Jest to lokalny bufor do przechowywania danych i w rzeczywistości nie wpływa na ilość danych zwracanych przez sterownik ODBC. RFX_Text i RFX_Binary wykonaj tylko jedno wywołanie za pomocą polecenia SQLFetch , aby pobrać dane z bazy danych zaplecza. Każdy sterownik ODBC ma inne ograniczenie ilości danych, które mogą zwrócić w ramach pojedynczego pobierania. Ten limit może być znacznie mniejszy niż wartość ustawiona w nMaxLength, w tym przypadku wyjątek AFX_SQL_ERROR_DATA_TRUNCATED zostanie zgłoszony. W tych okolicznościach przełącz się na używanie RFX_LongBinary zamiast RFX_Text lub RFX_Binary tak, aby wszystkie dane mogły zostać pobrane.

Klasa ClassWizard będzie wiązać SQL_LONGVARCHAR z elementem CStringlub SQL_LONGVARBINARY CByteArray dla Ciebie. Jeśli chcesz przydzielić więcej niż 255 bajtów, do których pobierasz długą kolumnę danych, możesz podać jawną wartość dla nMaxLength.

Jeśli długa kolumna danych jest powiązana z wartością CString lub CByteArray, aktualizowanie pola działa tak samo, jak w przypadku, gdy jest ona powiązana z SQL_VARCHAR lub SQL_VARBINARY. W trakcie Editoperacji wartość danych jest buforowana i później porównywana, gdy Update jest wywoływana w celu wykrywania zmian w wartości danych i odpowiedniego ustawienia wartości Dirty i Null dla kolumny.

Wiązanie długiej kolumny danych z CLongBinary

Jeśli długa kolumna danych może zawierać więcej bajtów danych MAXINT , prawdopodobnie rozważ pobranie ich do elementu CLongBinary.

Zalety:

Spowoduje to pobranie całej długiej kolumny danych do dostępnej pamięci.

Wady:

Dane są przechowywane w pamięci. Takie podejście jest również zbyt drogie w przypadku bardzo dużych ilości danych. Musisz wywołać SetFieldDirty element członkowski powiązanych danych, aby upewnić się, że pole jest uwzględnione w Update operacji.

W przypadku pobierania długich kolumn danych do CLongBinaryklasy baz danych będą sprawdzać całkowity rozmiar długiej kolumny danych, a następnie przydzielić HGLOBAL segment pamięci wystarczająco duży, aby pomieścić całą wartość danych. Klasy baz danych następnie pobierają całą wartość danych do przydzielonego HGLOBALelementu .

Jeśli źródło danych nie może zwrócić oczekiwanego rozmiaru długiej kolumny danych, struktura zgłosi wyjątek AFX_SQL_ERROR_SQL_NO_TOTAL. Jeśli próba przydzielenia elementu HGLOBAL zakończy się niepowodzeniem, zostanie zgłoszony wyjątek pamięci standardowej.

Klasa ClassWizard będzie wiązać SQL_LONGVARCHAR lub SQL_LONGVARBINARY dla CLongBinary Ciebie. Wybierz CLongBinary jako typ zmiennej w oknie dialogowym Dodawanie zmiennej składowej. KlasaWizard doda wywołanie wywołania DoFieldExchange i zwiększy łączną RFX_LongBinary liczbę powiązanych pól.

Aby zaktualizować długie wartości kolumn danych, najpierw upewnij się, że przydzielone HGLOBAL dane są wystarczająco duże, aby przechowywać nowe dane, wywołując metodę ::GlobalSize w m_hData elementu członkowskiego CLongBinary. Jeśli jest za mały, zwolnij HGLOBAL i przydziel jeden odpowiedni rozmiar. Następnie ustaw m_dwDataLength , aby odzwierciedlić nowy rozmiar.

W przeciwnym razie, jeśli m_dwDataLength jest większy niż rozmiar zastępowanych danych, możesz zwolnić i ponownie przydzielić HGLOBALelement lub pozostawić przydzielone. Pamiętaj, aby wskazać liczbę bajtów używanych w m_dwDataLength.

Jak działa aktualizowanie obiektu CLongBinary

Nie jest konieczne zrozumienie sposobu działania aktualizacji CLongBinary , ale może być przydatne jako przykład sposobu wysyłania długich wartości danych do źródła danych, jeśli wybierzesz tę trzecią metodę, opisaną poniżej.

Uwaga

Aby CLongBinary pole było uwzględnione w aktualizacji, należy jawnie wywołać SetFieldDirty pole. Jeśli wprowadzisz dowolną zmianę w polu, w tym ustawienie wartości Null, musisz wywołać metodę SetFieldDirty. Należy również wywołać metodę SetFieldNull, a drugi parametr ma wartość FALSE, aby oznaczyć pole jako wartość.

Podczas aktualizowania CLongBinary pola klasy baz danych używają mechanizmu DATA_AT_EXEC ODBC (zobacz dokumentację ODBC dotyczącą SQLSetPosargumentu rgbValue). Gdy platforma przygotowuje instrukcję wstawiania lub aktualizacji, zamiast wskazywać HGLOBAL na zawierające dane, adres CLongBinary jest ustawiany jako wartość kolumny, a wskaźnik długości ustawiony na SQL_DATA_AT_EXEC. Później po wysłaniu instrukcji update do źródła SQLExecDirect danych zostanie zwrócona SQL_NEED_DATA. Spowoduje to alerty struktury, w przypadku których wartość parametru dla tej kolumny jest w rzeczywistości adresem CLongBinary. Struktura wywołuje raz SQLGetData z małym buforem, spodziewając się, że sterownik zwróci rzeczywistą długość danych. Jeśli sterownik zwraca rzeczywistą długość binarnego dużego obiektu (BLOB), MFC reallocuje tyle miejsca, ile jest potrzebne do pobrania obiektu BLOB. Jeśli źródło danych zwróci SQL_NO_TOTAL, co oznacza, że nie może określić rozmiaru obiektu BLOB, usługa MFC utworzy mniejsze bloki. Domyślny rozmiar początkowy to 64K, a kolejne bloki będą mieć dwukrotnie większy rozmiar; na przykład drugi będzie wynosić 128 000, trzeci to 256 tys. itd. Rozmiar początkowy można skonfigurować.

Niewiążące: pobieranie/wysyłanie danych bezpośrednio z odBC za pomocą funkcji SQLGetData

Dzięki tej metodzie całkowicie pomijasz klasy baz danych i samodzielnie zajmujesz się długą kolumną danych.

Zalety:

W razie potrzeby możesz buforować dane na dysku lub zdecydować dynamicznie, ile danych chcesz pobrać.

Wady:

Nie uzyskujesz Edit obsługi ani AddNew struktury i musisz napisać kod samodzielnie, aby wykonać podstawowe funkcje (Delete działa jednak, ponieważ nie jest to operacja na poziomie kolumny).

W takim przypadku długa kolumna danych musi znajdować się na liście wyboru zestawu rekordów, ale nie powinna być powiązana ze strukturą. Jednym ze sposobów wykonania tej czynności jest podanie własnej instrukcji SQL za pośrednictwem GetDefaultSQL argumentu lpszSQL funkcji CRecordsetlub jako argumentu Open lpszSQL, a nie powiązania dodatkowej kolumny z wywołaniem funkcji RFX_. OdBC wymaga, aby pola niepowiązane wydawały się być wyświetlane po prawej stronie powiązanych pól, dlatego dodaj niezwiązaną kolumnę lub kolumny na końcu listy wyboru.

Uwaga

Ponieważ długa kolumna danych nie jest powiązana ze strukturą, zmiany w niej nie będą obsługiwane za pomocą CRecordset::Update wywołań. Musisz utworzyć i wysłać wymagane instrukcje SQL INSERT i UPDATE samodzielnie.

Zobacz też

Uwagi techniczne według numerów
Uwagi techniczne według kategorii