DBMSs는 255자 같은 특정 크기에 걸쳐 긴 데이터를 문자 또는 이진 데이터로 정의합니다. 이 데이터는 수천 개의 문자에 대한 부분 설명과 같이 단일 버퍼에 저장할 수 있을 만큼 작을 수 있습니다. 그러나 긴 텍스트 문서 또는 비트맵과 같이 메모리에 저장하기에는 너무 길 수 있습니다. 이러한 데이터는 단일 버퍼에 저장할 수 없으므로 행의 다른 데이터를 가져온 후 SQLGetData 가 있는 부분의 드라이버에서 검색됩니다.
비고
애플리케이션은 실제로 긴 데이터뿐만 아니라 문자 및 이진 데이터와 같이 부분적으로 검색할 수 있는 데이터를 포함하여 SQLGetData로 모든 형식의 데이터를 검색할 수 있습니다. 그러나 데이터가 단일 버퍼에 맞게 충분히 작은 경우 일반적으로 SQLGetData를 사용할 이유가 없습니다. 버퍼를 열에 바인딩하고 드라이버가 버퍼의 데이터를 반환하도록 하는 것이 훨씬 쉽습니다.
열에서 긴 데이터를 검색하기 위해 애플리케이션은 먼저 SQLFetchScroll 또는 SQLFetch 를 호출하여 행으로 이동하고 바인딩된 열에 대한 데이터를 가져옵니다. 그런 다음, 애플리케이션은 SQLGetData를 호출합니다. SQLGetData 함수는 SQLBindCol과 동일한 인수를 사용합니다. 문 핸들, 열 번호, 애플리케이션 변수의 C 데이터 형식, 주소 및 바이트 길이, 그리고 길이/표시기 버퍼의 주소가 포함됩니다. 두 함수는 기본적으로 동일한 작업을 수행하기 때문에 동일한 인수를 갖습니다. 둘 다 드라이버에 애플리케이션 변수를 설명하고 특정 열에 대한 데이터를 해당 변수에 반환하도록 지정합니다. 주요 차이점은 행을 가져온 후 SQLGetData 가 호출되고(이러한 이유로 지연 바인딩 이라고도 함) SQLGetData 에서 지정한 바인딩이 호출 기간 동안만 지속된다는 점입니다.
단일 열과 관련하여 SQLGetData 는 SQLFetch와 같이 동작합니다. 열에 대한 데이터를 검색하고, 애플리케이션 변수의 형식으로 변환하고, 해당 변수에 반환합니다. 또한 길이/표시기 버퍼에 있는 데이터의 바이트 길이를 반환합니다. SQLFetch가 데이터를 반환하는 방법에 대한 자세한 내용은 데이터 행 가져오기를 참조하세요.
SQLGetData 는 한 가지 중요한 측면에서 SQLFetch 와 다릅니다. 동일한 열에 대해 두 번 이상 연속으로 호출되는 경우 각 호출은 데이터의 연속 부분을 반환합니다. 마지막 호출을 제외한 각 호출은 SQL_SUCCESS_WITH_INFO 및 SQLSTATE 01004(문자열 데이터, 오른쪽 잘림)를 반환합니다. 마지막 호출은 SQL_SUCCESS 반환합니다. 이는 SQLGetData 를 사용하여 부분의 긴 데이터를 검색하는 방법입니다. 반환할 데이터가 더 이상 없으면 SQLGetData 는 SQL_NO_DATA 반환합니다. 애플리케이션은 긴 데이터를 함께 배치하는 역할을 하며, 이는 데이터의 일부를 연결하는 것을 의미할 수 있습니다. 각 부분은 null로 종료됩니다. 파트를 연결하는 경우 애플리케이션에서 null 종료 문자를 제거해야 합니다. 부분의 데이터 검색은 가변 길이 책갈피뿐만 아니라 다른 긴 데이터에 대해서도 수행할 수 있습니다. 길이/표시기 버퍼에 반환된 값은 각 호출에서 이전 호출에서 반환된 바이트 수만큼 감소합니다. 드라이버가 사용 가능한 데이터의 양을 발견하지 못하고 SQL_NO_TOTAL을 반환하는 것이 일반적입니다. 다음은 그 예입니다.
// Declare a binary buffer to retrieve 5000 bytes of data at a time.
SQLCHAR BinaryPtr[5000];
SQLUINTEGER PartID;
SQLINTEGER PartIDInd, BinaryLenOrInd, NumBytes;
SQLRETURN rc;
SQLHSTMT hstmt;
// Create a result set containing the ID and picture of each part.
SQLExecDirect(hstmt, "SELECT PartID, Picture FROM Pictures", SQL_NTS);
// Bind PartID to the PartID column.
SQLBindCol(hstmt, 1, SQL_C_ULONG, &PartID, 0, &PartIDInd);
// Retrieve and display each row of data.
while ((rc = SQLFetch(hstmt)) != SQL_NO_DATA) {
// Display the part ID and initialize the picture.
DisplayID(PartID, PartIDInd);
InitPicture();
// Retrieve the picture data in parts. Send each part and the number
// of bytes in each part to a function that displays it. The number
// of bytes is always 5000 if there were more than 5000 bytes
// available to return (cbBinaryBuffer > 5000). Code to check if
// rc equals SQL_ERROR or SQL_SUCCESS_WITH_INFO not shown.
while ((rc = SQLGetData(hstmt, 2, SQL_C_BINARY, BinaryPtr, sizeof(BinaryPtr),
&BinaryLenOrInd)) != SQL_NO_DATA) {
NumBytes = (BinaryLenOrInd > 5000) || (BinaryLenOrInd == SQL_NO_TOTAL) ?
5000 : BinaryLenOrInd;
DisplayNextPictPart(BinaryPtr, NumBytes);
}
}
// Close the cursor.
SQLCloseCursor(hstmt);
SQLGetData 사용에는 몇 가지 제한 사항이 있습니다. 일반적으로 SQLGetData를 사용하여 액세스하는 열은 다음과 같습니다.
열 번호가 증가하는 순서대로 액세스해야 합니다(결과 집합의 열을 데이터 원본에서 읽는 방식 때문). 예를 들어 열 5에 대해 SQLGetData 를 호출한 다음 열 4에 대해 호출하는 것은 오류입니다.
바인딩할 수 없습니다.
마지막 바인딩된 열보다 더 높은 열 번호가 있어야 합니다. 예를 들어 마지막 바인딩된 열이 열 3인 경우 열 2에 대해 SQLGetData 를 호출하는 것은 오류입니다. 이러한 이유로 애플리케이션은 긴 데이터 열을 선택 목록의 끝에 배치해야 합니다.
둘 이상의 행을 검색하기 위해 SQLFetch 또는 SQLFetchScroll 을 호출한 경우에는 사용할 수 없습니다. 자세한 내용은 블록 커서 사용을 참조하세요.
일부 드라이버는 이러한 제한을 적용하지 않습니다. 상호 운용 가능한 애플리케이션은 해당 애플리케이션이 있다고 가정하거나 SQL_GETDATA_EXTENSIONS 옵션으로 SQLGetInfo 를 호출하여 적용되지 않는 제한을 결정해야 합니다.
애플리케이션에 문자 또는 이진 데이터 열의 모든 데이터가 필요하지 않은 경우 문을 실행하기 전에 SQL_ATTR_MAX_LENGTH 문 특성을 설정하여 DBMS 기반 드라이버의 네트워크 트래픽을 줄일 수 있습니다. 이렇게 하면 문자 또는 이진 열에 대해 반환될 데이터 바이트 수가 제한됩니다. 예를 들어 열에 긴 텍스트 문서가 포함되어 있다고 가정합니다. 이 열이 포함된 테이블을 찾아보는 애플리케이션은 각 문서의 첫 페이지만 표시해야 할 수 있습니다. 이 문 특성은 드라이버에서 시뮬레이션할 수 있지만 이 작업을 수행할 이유가 없습니다. 특히 애플리케이션이 문자 또는 이진 데이터를 자르려는 경우 작은 버퍼를 SQLBindCol 을 사용하여 열에 바인딩하고 드라이버가 데이터를 자르도록 해야 합니다.