TN045: Obsługa długich Varchar/Varbinary w MFC/bazy danych
[!UWAGA]
Następujące Uwaga techniczna została zaktualizowana, ponieważ najpierw została uwzględniona w dokumentacji online.W rezultacie niektóre procedur i tematów może być nieaktualne lub nieprawidłowe.Najnowsze informacje zaleca się wyszukać temat zainteresowanie Indeks dokumentacji online.
Uwaga ta opisuje sposób pobierania i wysyłania ODBC SQL_LONGVARCHAR i SQL_LONGVARBINARY za pomocą MFC typów danych bazy danych klasy.
Omówienie długie Varchar/Varbinary obsługuje
ODBC SQL_LONG_VARCHAR i SQL_LONGBINARY (tu mowa jak długo kolumny danych) typy danych może pomieścić ogromne ilości danych.Można obsługiwać tych danych na 3 sposoby:
Bind it to a CString/CByteArray.
Powiązać go z CLongBinary.
Nie związać go wcale i pobierania i wysyłania wartości danych long ręcznie, niezależnie od klasy bazy danych.
Każda z trzech metod ma wady i zalety.
Kolumny danych długich nie są obsługiwane dla parametrów kwerendy.Są obsługiwane dla outputColumns.
Wiązanie kolumny danych Long CString/CByteArray
Zalety:
To podejście jest proste do zrozumienia i pracy z klasami znane.Zapewnia ramy CFormView obsługa CString z DDX_Text.Masz dużo ogólne funkcje ciąg lub kolekcji z CString i CByteArray klasy, a można kontrolować ilość pamięci lokalnie do przechowywania wartości danych.Ramy utrzymuje starej kopii danych pola podczas Edytuj lub AddNew wywołania funkcji i can framework automatycznie wykryć zmiany w danych.
[!UWAGA]
Ponieważ CString jest przeznaczony do pracy z danych znakowych i CByteArray do pracy na dane binarne, zaleca się umieszczenie danych znakowych (SQL_LONGVARCHAR) w CStringi dane binarne (SQL_LONGVARBINARY) w CByteArray.
Funkcje RFX dla CString i CByteArray ma dodatkowy argument pozwala zastąpić domyślny rozmiar alokacji pamięci do przechowywania pobrana wartość dla kolumny danych.Uwaga argumentu nMaxLength w następującej deklaracji 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);
Jeśli pobieranie kolumny danych long do CString lub CByteArray, maksymalna zwracane ilości danych jest domyślnie 255 bajtów.Nic poza ten jest ignorowany.W tym przypadku ramach wygeneruje wyjątek AFX_SQL_ERROR_DATA_TRUNCATED.Na szczęście można jawnie zwiększyć nMaxLength większej wartości do MAXINT.
[!UWAGA]
Wartość nMaxLength jest używane przez MFC, aby ustawić lokalne bufor SQLBindColumn funkcji.To jest lokalny bufor do przechowywania danych i nie wpływa faktycznie ilość danych zwracanych przez sterownik ODBC.RFX_Texti RFX_Binary tylko zgłosić jedno wywołanie przy użyciu SQLFetch do pobierania danych z bazy danych typu back-end.Każdy sterownik ODBC ma różne ograniczenia na ilość danych, którą może przywrócić pojedynczego pobrania.Limit ten może być znacznie mniejsza niż wartość w nMaxLength, w którym to przypadku wyjątek AFX_SQL_ERROR_DATA_TRUNCATED wygeneruje.W tych okolicznościach, przełącz się do za pomocą RFX_LongBinary zamiast RFX_Text lub RFX_Binary tak, aby wszystkie dane mogą być pobierane.
Nada ClassWizard SQL_LONGVARCHAR do CString, lub SQL_LONGVARBINARY do CByteArray dla Ciebie.Aby przydzielić więcej niż 255 bajtów, do których można pobrać kolumny danych long, można następnie podać jawną wartość dla nMaxLength.
Kiedy jest powiązana kolumna danych long CString lub CByteArray, uaktualniania pola działa tak samo jak, kiedy jest on związany z SQL_VARCHAR lub SQL_VARBINARY.Podczas Edytuj, wartość danych jest buforowany away i później, po porównaniu Aktualizacja jest wywoływana w celu wykrywania zmiany danych wartości i ustawić Dirty i odpowiednio Null wartości dla kolumny.
Wiązanie kolumny danych Long CLongBinary
Jeśli kolumny danych long może zawierać więcej MAXINT bajtów danych, prawdopodobnie warto ją do pobierania CLongBinary.
Zalety:
Pobiera to kolumna danych long całego do dostępnej pamięci.
Wady:
Dane są przechowywane w pamięci.To podejście jest również patentowymi bardzo duże ilości danych.Musisz wywołać SetFieldDirty dla dane powiązane Członkowskie zapewniające pole znajduje się w Aktualizacja operacji.
Jeśli pobieranie danych long kolumn do CLongBinary, klas bazy danych będzie całkowity rozmiar kolumny danych long, a następnie przydzielić HGLOBAL żeby wartość danych całego segmentu pamięci.Klasy bazy danych następnie pobrać wartości danych do przydzielonego HGLOBAL.
Jeśli źródło danych nie może zwrócić oczekiwanych rozmiar kolumny danych long, ramach wygeneruje wyjątek AFX_SQL_ERROR_SQL_NO_TOTAL.Jeśli próba zaalokowania HGLOBAL się nie powiedzie, standardowe pamięci jest wyjątek.
Nada ClassWizard SQL_LONGVARCHAR lub SQL_LONGVARBINARY do CLongBinary dla Ciebie.Wybierz CLongBinary jako typ zmiennej w oknie dialogowym Dodawanie Członkowskie zmiennej.ClassWizard spowoduje dodanie RFX_LongBinary wywołanie your DoFieldExchange wywołania i zwiększyć całkowitą liczbę pól związanego.
Zaktualizować długie wartości kolumny danych, najpierw upewnij się przydzielonego HGLOBAL jest wystarczająco duże do pomieszczenia nowych danych, wywołując :: Funkcja GlobalSize na m_hData członek CLongBinary.Jeśli jest za mały, zwolnić HGLOBAL i przydzielić jedną odpowiedni rozmiar.Następnie ustaw m_dwDataLength w celu odzwierciedlenia nowego rozmiaru.
Inaczej, jeśli m_dwDataLength jest większy niż rozmiar danych chcesz zamienić, można zwolnić i Alokacja HGLOBAL, lub pozostawić ją przydzielone.Upewnij się, że wskazuje liczbę bajtów faktycznie używanych w m_dwDataLength.
W jaki sposób aktualizowania działa CLongBinary
Nie jest konieczne do zrozumienia sposobu aktualizowania CLongBinary programu works, ale może być przydatna na przykład dotyczące wysyłania wartości danych long ze źródłem danych, jeśli wybierzesz ten trzeci, opisaną poniżej metodą.
[!UWAGA]
W celu CLongBinary pola, które mają zostać uwzględnione w aktualizacji, należy jawnie wywołać SetFieldDirty dla pola.Jeśli wszystkie zmiany do pola, w tym ustawienie wartości Null, należy wywołać SetFieldDirty.Musisz wywołać SetFieldNull, z drugi parametr jest FALSE, aby oznaczyć pole jako posiadające wartość.
Podczas aktualizacji CLongBinary pola bazy danych używają ODBC's DATA_AT_EXEC mechanizmu (zobacz dokumentację ODBC w SQLSetPos's rgbValue argument).Gdy w ramach przygotowuje instrukcji insert lub update, zamiast wskazywać polecenie HGLOBAL zawierający dane, adres z CLongBinary jest ustawiony jako wartość kolumny zamiast i ustaw wskaźnik długość SQL_DATA_AT_EXEC.Później, kiedy instrukcja update jest wysyłana do źródła danych, SQLExecDirect zwróci SQL_NEED_DATA.Alerty ramach że wartości parametrów dla tej kolumny jest rzeczywiście adresem CLongBinary.Rozmowy w ramach SQLGetData raz z małym buforem, oczekiwano sterownika, aby powrócić do rzeczywistej długości danych.Jeśli sterownik zwraca wartość rzeczywista długość dużego obiektu binarnego (BLOB), MFC reallocates tyle miejsca niezbędnych do pobrania obiektu BLOB.Jeśli źródło danych zwraca SQL_NO_TOTAL, wskazując, że nie można określić rozmiar obiektu BLOB, MFC utworzy mniejsze bloki.Początkowy rozmiar domyślny to 64 KB, a kolejne bloki będą dwukrotnie rozmiar; na przykład drugi będzie 128 K, trzeci jest 256 K i tak dalej.Konfiguruje się początkowy rozmiar.
Nie są wiążące: Pobieranie/wysyłanie danych bezpośrednio z ODBC z SQLGetData
Z tej metody można całkowicie pominąć klas bazy danych i postępowania z kolumną danych long.
Zalety:
Może buforować dane do dysku, jeżeli jest to konieczne, lub zdecydować dynamicznie ilości danych do pobierania.
Wady:
Nie otrzymasz w ramach Edytuj lub AddNew wsparcia i użytkownik musi zapisać kod samodzielnie wykonywać podstawowe funkcje (usunąć pracy, ponieważ nie jest operacją poziomu kolumny).
W tym przypadku kolumnę danych long musi być na liście wybierz zestaw rekordów, ale nie powinna być zobowiązana do ramy.Jedną stronę, aby zrobić to dostaw własną instrukcję SQL, via GetDefaultSQL lub jako lpszSQL argument CRecordset's Otwórz działać, a nie wiążą się dodatkowe kolumny za pomocą wywołania funkcji RFX_.ODBC wymaga, że niezwiązanego pola są wyświetlane po prawej stronie pól związanego, tak dodać na końcu listy wybierz niezwiązany kolumny lub kolumn.
[!UWAGA]
Ponieważ kolumny danych long nie jest związana w ramach, zmiany nie będą przetwarzane z CRecordset::Update wywołań.Należy utworzyć i wysłać wymagane SQL WSTAWIĆ i Aktualizacja sprawozdania samodzielnie.