다음을 통해 공유


TN045: Long Varchar/Varbinary에 대한 MFC/데이터베이스 지원

참고 항목

다음 기술 노트는 온라인 설명서에 먼저 포함되어 있었으므로 업데이트되지 않았습니다. 따라서 일부 절차 및 항목은 만료되거나 올바르지 않을 수 있습니다. 최신 정보를 보려면 온라인 설명서 색인에서 관심 있는 항목을 검색하는 것이 좋습니다.

이 참고에서는 MFC 데이터베이스 클래스를 사용하여 ODBC SQL_LONGVARCHAR 및 SQL_LONGVARBINARY 데이터 형식을 검색 및 전송하는 방법을 설명합니다.

Long Varchar/Varbinary 지원 개요

ODBC SQL_LONG_VARCHARSQL_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 또는 CByteArray255바이트로 검색하는 경우 반환되는 최대 데이터 양은 기본적으로 255바이트입니다. 이 외의 모든 항목은 무시됩니다. 이 경우 프레임워크는 예외 AFX_SQL_ERROR_DATA_TRUNCATED throw합니다. 다행히 nMaxLength를 MAXINT까지 더 큰 값으로 명시적으로 늘릴 수 있습니다.

참고 항목

nMaxLength 값은 MFC에서 함수의 SQLBindColumn 로컬 버퍼를 설정하는 데 사용됩니다. 이 버퍼는 데이터 스토리지에 대한 로컬 버퍼이며 실제로 ODBC 드라이버에서 반환되는 데이터의 양에 영향을 주지 않습니다. RFX_TextRFX_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 인수에 대한 SQLSetPosODBC 설명서 참조). 프레임워크가 데이터를 포함하는 것을 가리키는 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 문을 함수에 CRecordsetOpen 제공하고 추가 열을 RFX_ 함수 호출과 바인딩하지 않는 것입니다. ODBC를 사용하려면 바인딩된 필드 오른쪽에 언바운드 필드가 표시되어야 하므로 선택 목록의 끝에 언바운드 열 또는 열을 추가합니다.

참고 항목

긴 데이터 열이 프레임워크에 바인딩되지 않으므로 변경 내용은 호출로 CRecordset::Update 처리되지 않습니다. 필요한 SQL INSERTUPDATE 문을 직접 만들고 보내야 합니다.

참고 항목

번호별 기술 참고 사항
범주별 기술 참고 사항