TN045: Long Varchar/Varbinary에 대한 MFC/데이터베이스 지원
참고 항목
다음 기술 노트는 온라인 설명서에 먼저 포함되어 있었으므로 업데이트되지 않았습니다. 따라서 일부 절차 및 항목은 만료되거나 올바르지 않을 수 있습니다. 최신 정보를 보려면 온라인 설명서 색인에서 관심 있는 항목을 검색하는 것이 좋습니다.
이 참고에서는 MFC 데이터베이스 클래스를 사용하여 ODBC SQL_LONGVARCHAR 및 SQL_LONGVARBINARY 데이터 형식을 검색 및 전송하는 방법을 설명합니다.
Long Varchar/Varbinary 지원 개요
ODBC SQL_LONG_VARCHAR 및 SQL_LONGBINARY 데이터 형식(여기서는 긴 데이터 열이라고 함)은 엄청난 양의 데이터를 보유할 수 있습니다. 다음 세 가지 방법으로 이 데이터를 처리할 수 있습니다.
에 바인딩합니다
CString
/CByteArray
.에 바인딩합니다
CLongBinary
.데이터베이스 클래스와 관계없이 이 값을 전혀 바인딩하지 않고 긴 데이터 값을 수동으로 검색하고 전송하지 마세요.
세 가지 방법 각각에는 장점과 단점이 있습니다.
긴 데이터 열은 쿼리에 대한 매개 변수에 대해 지원되지 않습니다. outputColumns에 대해서만 지원됩니다.
CString/CByteArray에 긴 데이터 열 바인딩
장점:
이 방법은 이해하기 쉽고 익숙한 클래스로 작업합니다. 프레임워크는 .에 DDX_Text
대한 CString
지원을 제공합니다CFormView
. 및 CByteArray
클래스와 함께 CString
많은 일반 문자열 또는 컬렉션 기능이 있으며, 데이터 값을 보유하기 위해 로컬로 할당된 메모리 양을 제어할 수 있습니다. 프레임워크는 기본 또는 AddNew
함수 호출 중에 Edit
필드 데이터의 이전 복사본을 획득하며 프레임워크는 자동으로 데이터의 변경 내용을 검색할 수 있습니다.
참고 항목
CString
문자 데이터 작업 및 CByteArray
이진 데이터 작업을 위해 설계되었으므로 문자 데이터(SQL_LONGVARCHAR)CString
와 이진 데이터(SQL_LONGVARBINARY)를 배치하는 CByteArray
것이 좋습니다.
RFX 함수는 CByteArray
데이터 열에 대해 CString
검색된 값을 보유하도록 할당된 메모리의 기본 크기를 재정의할 수 있는 추가 인수를 사용합니다. 다음 함수 선언에서 nMaxLength 인수를 확인합니다.
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);
긴 데이터 열을 a CString
또는 CByteArray
255바이트로 검색하는 경우 반환되는 최대 데이터 양은 기본적으로 255바이트입니다. 이 외의 모든 항목은 무시됩니다. 이 경우 프레임워크는 예외 AFX_SQL_ERROR_DATA_TRUNCATED throw합니다. 다행히 nMaxLength를 MAXINT까지 더 큰 값으로 명시적으로 늘릴 수 있습니다.
참고 항목
nMaxLength 값은 MFC에서 함수의 SQLBindColumn
로컬 버퍼를 설정하는 데 사용됩니다. 이 버퍼는 데이터 스토리지에 대한 로컬 버퍼이며 실제로 ODBC 드라이버에서 반환되는 데이터의 양에 영향을 주지 않습니다. RFX_Text
백 RFX_Binary
엔드 데이터베이스에서 데이터를 검색하는 데 한 SQLFetch
번만 호출합니다. 각 ODBC 드라이버는 단일 페치에서 반환할 수 있는 데이터의 양에 대해 서로 다른 제한을 가합니다. 이 제한은 nMaxLength에 설정된 값보다 훨씬 작을 수 있으며, 이 경우 예외 AFX_SQL_ERROR_DATA_TRUNCATED throw됩니다. 이러한 상황에서는 모든 데이터를 검색할 수 있도록 대신 RFX_Text
RFX_Binary
사용 RFX_LongBinary
으로 전환합니다.
ClassWizard는 SQL_LONGVARCHAR CString
바인딩하거나 SQL_LONGVARBINARY CByteArray
바인딩합니다. 긴 데이터 열을 검색할 255바이트 이상을 할당하려는 경우 nMaxLength에 대한 명시적 값을 제공할 수 있습니다.
긴 데이터 열이 A CString
또는 CByteArray
에 바인딩된 경우 필드 업데이트는 SQL_VARCHAR 또는 SQL_VARBINARY에 바인딩된 경우와 동일하게 작동합니다. 이 동안 Edit
데이터 값은 캐시되고 나중에 데이터 값의 변경 내용을 검색하고 열에 대한 Dirty 및 Null 값을 적절하게 설정하기 위해 호출될 때 Update
비교됩니다.
CLongBinary에 긴 데이터 열 바인딩
긴 데이터 열에 더 많은 MAXINT 바이트의 데이터가 포함될 수 있는 경우 해당 데이터를 .로 CLongBinary
검색하는 것이 좋습니다.
장점:
이렇게 하면 사용 가능한 메모리까지 전체 긴 데이터 열을 검색합니다.
단점
데이터는 메모리에 보관됩니다. 이 방법은 매우 많은 양의 데이터에 대해서도 엄청나게 비용이 많이 듭니다. 바인딩된 데이터 멤버를 호출 SetFieldDirty
하여 필드가 작업에 포함 Update
되도록 해야 합니다.
긴 데이터 열을 검색하는 경우 데이터베이스 클래스는 긴 데이터 열CLongBinary
의 총 크기를 검사 전체 데이터 값을 보유할 수 있을 만큼 큰 메모리 세그먼트를 할당 HGLOBAL
합니다. 그런 다음 데이터베이스 클래스는 전체 데이터 값을 할당된 HGLOBAL
값으로 검색합니다.
데이터 원본이 긴 데이터 열의 예상 크기를 반환할 수 없는 경우 프레임워크는 예외 AFX_SQL_ERROR_SQL_NO_TOTAL throw합니다. 할당 HGLOBAL
시도가 실패하면 표준 메모리 예외가 throw됩니다.
ClassWizard는 SQL_LONGVARCHAR 또는 SQL_LONGVARBINARY 사용자를 위해 CLongBinary
바인딩합니다. 멤버 변수 추가 대화 상자에서 변수 형식으로 선택합니다 CLongBinary
. 그러면 ClassWizard가 호출에 호출을 DoFieldExchange
추가하고 RFX_LongBinary
바인딩된 필드의 총 수를 증분합니다.
긴 데이터 열 값을 업데이트하려면 먼저 할당된 HGLOBAL
값이 m_hData 멤버CLongBinary
에서 ::GlobalSize를 호출하여 새 데이터를 저장할 수 있을 만큼 큰지 확인합니다. 너무 작은 경우 해당 크기를 해제 HGLOBAL
하고 할당합니다. 그런 다음 새 크기를 반영하도록 m_dwDataLength 설정합니다.
그렇지 않은 경우 m_dwDataLength 대체하려는 데이터의 크기보다 큰 경우 데이터를 해제하고 다시 할당하거나 할당된 HGLOBAL
상태로 둘 수 있습니다. m_dwDataLength 실제로 사용되는 바이트 수를 나타내야 합니다.
CLongBinary 업데이트 작동 방식
업데이트 CLongBinary
가 작동하는 방식을 이해할 필요는 없지만 아래에 설명된 이 세 번째 방법을 선택하는 경우 데이터 원본에 긴 데이터 값을 보내는 방법에 대한 예제로 유용할 수 있습니다.
참고 항목
업데이트에 CLongBinary
필드를 포함하려면 필드를 명시적으로 호출 SetFieldDirty
해야 합니다. Null 설정을 포함하여 필드를 변경하는 경우 호출 SetFieldDirty
해야 합니다. 두 번째 매개 변수가 FALSE인 상태에서 필드를 값으로 표시하려면 호출SetFieldNull
해야 합니다.
필드를 업데이트 CLongBinary
할 때 데이터베이스 클래스는 ODBC의 DATA_AT_EXEC 메커니즘을 사용합니다('rgbValue 인수에 대한 SQLSetPos
ODBC 설명서 참조). 프레임워크가 데이터를 포함하는 것을 가리키는 HGLOBAL
대신 insert 또는 update 문을 준비하면 해당 주소 CLongBinary
가 대신 열 값으로 설정되고 길이 표시기가 SQL_DATA_AT_EXEC 설정됩니다. 나중에 업데이트 문이 데이터 원본 SQLExecDirect
으로 전송되면 SQL_NEED_DATA 반환됩니다. 이렇게 하면 이 열의 매개 변수 값이 실제로 .의 주소임을 프레임워크에 알릴 수 있습니다 CLongBinary
. 프레임워크는 드라이버가 데이터의 실제 길이를 반환할 것으로 예상하는 작은 버퍼를 사용하여 한 번 호출 SQLGetData
합니다. 드라이버가 BLOB(Binary Large Object)의 실제 길이를 반환하는 경우 MFC는 BLOB을 가져오는 데 필요한 만큼의 공간을 다시 할당합니다. 데이터 원본이 BLOB의 크기를 확인할 수 없음을 나타내는 SQL_NO_TOTAL 반환하는 경우 MFC는 더 작은 블록을 만듭니다. 기본 초기 크기는 64K이고 후속 블록은 크기가 두 배가 됩니다. 예를 들어 두 번째는 128K, 세 번째는 256K 등이 됩니다. 초기 크기는 구성할 수 있습니다.
바인딩 안 됨: SQLGetData를 사용하여 ODBC에서 직접 데이터 검색/보내기
이 메서드를 사용하면 데이터베이스 클래스를 완전히 무시하고 긴 데이터 열을 직접 처리할 수 있습니다.
장점:
필요한 경우 디스크에 데이터를 캐시하거나 검색할 데이터의 양을 동적으로 결정할 수 있습니다.
단점
프레임워크 Edit
또는 지원을 받지 못하며 AddNew
기본 기능을 수행하기 위해 코드를 직접 작성해야 합니다(Delete
열 수준 작업이 아니므로 작동).
이 경우 긴 데이터 열은 레코드 집합의 선택 목록에 있어야 하지만 프레임워크에 의해 바인딩되지 않아야 합니다. 이 작업을 수행하는 한 가지 방법은 lpszSQL 인수를 통해 GetDefaultSQL
또는 lpszSQL 인수로 고유한 SQL 문을 함수에 CRecordset
Open
제공하고 추가 열을 RFX_ 함수 호출과 바인딩하지 않는 것입니다. ODBC를 사용하려면 바인딩된 필드 오른쪽에 언바운드 필드가 표시되어야 하므로 선택 목록의 끝에 언바운드 열 또는 열을 추가합니다.
참고 항목
긴 데이터 열이 프레임워크에 바인딩되지 않으므로 변경 내용은 호출로 CRecordset::Update
처리되지 않습니다. 필요한 SQL INSERT 및 UPDATE 문을 직접 만들고 보내야 합니다.