다음을 통해 공유


결과 데이터 인출

ODBC 응용 프로그램에는 결과 데이터를 인출하기 위한 세 가지 옵션이 있습니다.

첫 번째 옵션은 SQLBindCol에 기반을 둡니다. 결과 집합을 인출하기 전에 응용 프로그램은 SQLBindCol을 사용하여 결과 집합의 각 열을 프로그램 변수에 바인딩합니다. 열이 바인딩된 후 응용 프로그램이 SQLFetch 또는 SQLFetchScroll을 호출할 때마다 드라이버는 현재 행의 데이터를 결과 집합 열에 바인딩된 변수에 전달합니다. 결과 집합 열과 프로그램 변수의 데이터 형식이 다르면 드라이버가 데이터 변환을 처리합니다. 응용 프로그램의 SQL_ATTR_ROW_ARRAY_SIZE가 1보다 큰 값으로 설정되어 있으면 응용 프로그램은 결과 열을 변수 배열에 바인딩할 수 있습니다. 그러면 SQLFetchScroll을 호출할 때마다 배열이 모두 채워집니다.

두 번째 옵션은 SQLGetData에 기반을 둡니다. 이 옵션을 사용할 경우 응용 프로그램이 SQLBindCol을 사용하여 결과 집합 열을 프로그램 변수에 바인딩하지 않습니다. SQLFetch를 호출할 때마다 응용 프로그램은 결과 집합의 각 열에 대해 한 번씩 SQLGetData를 호출합니다. SQLGetData는 특정 결과 집합 열의 데이터를 특정 프로그램 변수에 전달하도록 드라이버에 지시하고 열과 변수의 데이터 형식을 지정합니다. 이를 통해 드라이버는 결과 열과 프로그램 변수의 데이터 형식이 다를 경우 데이터를 변환할 수 있습니다. Text, ntextimage 열은 대개 너무 커서 프로그램 변수에 맞지 않지만 SQLGetData를 사용하여 검색할 수는 있습니다. 결과 열의 text, ntext 또는 image 데이터가 프로그램 변수보다 클 경우 SQLGetData가 SQL_SUCCESS_WITH_INFO 및 SQLSTATE 01004(문자열 데이터, 오른쪽이 잘림)를 반환합니다. SQLGetData에 대한 호출이 성공하면 일련의 text 또는 image 데이터의 청크가 반환됩니다. 데이터의 끝에 도달하면 SQLGetData가 SQL_SUCCESS를 반환합니다. SQL_ATTR_ROW_ARRAY_SIZE가 1보다 크면 각 인출에서 일련의 행 또는 행 집합을 반환합니다. SQLGetData를 사용하기 전에 먼저 SQLSetPos를 사용하여 행 집합 내의 특정 행을 현재 행으로 지정해야 합니다.

세 번째 옵션은 SQLBindColSQLGetData를 함께 사용하는 것입니다. 예를 들어 응용 프로그램은 결과 집합의 처음 10개 열을 바인딩한 다음 각 인출 작업 시 SQLGetData를 세 번 호출하여 바인딩되지 않은 세 개의 열에서 데이터를 검색할 수 있습니다. 이 방법은 일반적으로 결과 집합에 text 또는 image 열이 한 개 이상 포함된 경우에 사용합니다.

결과 집합에 대해 설정된 커서 옵션에 따라 응용 프로그램은 SQLFetchScroll 스크롤 옵션을 사용하여 결과 집합 내에서 스크롤할 수도 있습니다.

SQLBindCol을 사용하려면 ODBC 드라이버가 메모리를 할당해야 하므로 결과 집합 열을 프로그램 변수에 바인딩하기 위해 SQLBindCol을 자주 사용할 경우 비용이 많이 듭니다. 결과 열을 변수에 바인딩할 경우 SQLFreeHandle을 호출하여 문 핸들을 해제하거나 fOption을 QL_UNBIND로 설정하여 SQLFreeStmt를 호출할 때까지 바인딩 상태가 유지됩니다. 바인딩은 문이 완료될 때 자동으로 취소되지 않습니다.

이 논리를 이용해 서로 다른 매개 변수를 사용하는 동일 SELECT 문의 복수 실행을 효과적으로 처리할 수 있습니다. 결과 집합의 구조는 동일하게 유지되므로 결과 집합을 한 번만 바인딩하여 모든 SELECT 문을 처리할 수 있으며 그런 다음 마지막 문의 실행이 끝나면 fOption을 SQL_UNBIND로 설정하여 SQLFreeStmt를 호출하면 됩니다. SQLBindCol을 호출하여 결과 집합의 열을 바인딩하려면 먼저 fOption을 SQL_UNBIND로 설정해 SQLFreeStmt를 호출하여 이전 바인딩을 모두 해제해야 합니다.

SQLBindCol을 사용할 때 행 단위로 또는 열 단위로 바인딩할 수 있습니다. 행 단위 바인딩은 열 단위 바인딩보다 빠릅니다.

SQLBindCol을 사용하여 결과 집합 열을 바인딩하는 대신 SQLGetData를 사용하여 열 단위로 데이터를 검색할 수 있습니다. 결과 집합에 포함된 행이 몇 개 되지 않을 때는 SQLBindCol 대신 SQLGetData를 사용하는 것이 빠르지만 그렇지 않은 경우에는 SQLBindCol을 사용해야 최상의 성능을 얻을 수 있습니다. 데이터를 항상 동일한 변수 집합에 전달하지는 않으려는 경우 계속해서 다시 바인딩하는 대신 SQLGetData를 사용해야 합니다. SQLBindCol을 사용하여 모든 열을 바인딩한 후 SELECT 목록에 있는 열에 대해서만 SQLGetData를 사용할 수 있습니다. 또한 SELECT 목록에 있는 열은 이전에 SQLGetData를 사용한 적이 있는 다른 모든 열의 뒤에 나타나야 합니다.

SQLGetData, SQLBindColSQLBindParameter와 같이 프로그램 변수로 데이터를 가져오거나 프로그램 변수에서 데이터를 가져오는 작업을 처리하는 ODBC 함수는 암시적 데이터 형식 변환을 지원합니다. 예를 들어 응용 프로그램이 정수 열을 문자열 프로그램 변수에 바인딩할 경우 드라이버는 해당 데이터를 자동으로 정수에서 문자로 변환한 후 이를 프로그램 변수에 전달합니다.

응용 프로그램에서의 데이터 변환은 최소화해야 합니다. 응용 프로그램에서 수행하는 처리에 데이터 변환이 반드시 필요한 경우가 아니면 응용 프로그램은 열과 매개 변수를 동일한 형식의 프로그램 변수에 바인딩해야 합니다. 데이터 형식 변환이 반드시 필요한 경우에는 응용 프로그램에서가 아니라 드라이버가 변환을 수행하도록 하는 것이 효율적입니다. SQL Server Native Client ODBC 드라이버는 일반적으로 네트워크 버퍼에서 응용 프로그램의 변수에 직접 데이터를 전달합니다. 데이터 변환을 수행하도록 드라이버에 요청하면 드라이버는 데이터를 버퍼링한 후 CPU 주기를 사용하여 데이터를 변환합니다.

프로그램 변수는 text, ntextimage 데이터를 제외하고 열에서 전달된 데이터를 수용할 수 있을 만큼 커야 합니다. 응용 프로그램이 결과 집합 데이터를 검색한 후 해당 데이터를 수용하기에 너무 작은 변수에 데이터를 삽입하려고 하면 드라이버가 경고를 생성합니다. 이 경우 드라이버는 메시지에 사용할 메모리를 할당하게 되고 드라이버와 응용 프로그램 모두 메시지 및 오류 처리를 위해 CPU 주기를 사용해야 합니다. 응용 프로그램은 검색된 데이터를 수용할 수 있을 만큼 큰 변수를 할당하거나 SELECT 목록에서 SUBSTRING 함수를 사용하여 결과 집합의 열 크기를 줄여야 합니다.

SQL_C_DEFAULT를 사용하여 C 변수의 형식을 지정할 때는 주의를 기울여야 합니다. SQL_C_DEFAULT는 C 변수 형식이 열이나 매개 변수의 SQL 데이터 형식과 일치하도록 지정합니다. ntext, nchar 또는 nvarchar 열에 대해 SQL_C_DEFAULT를 지정하면 유니코드 데이터가 응용 프로그램에 반환됩니다. 유니코드 데이터를 처리하도록 응용 프로그램이 코딩되지 않은 경우 이로 인해 여러 가지 문제가 발생할 수 있습니다. uniqueidentifier(SQL_GUID) 데이터 형식의 경우에도 같은 종류의 문제가 발생할 수 있습니다.

text, ntextimage 데이터는 대개 단일 프로그램 변수에는 너무 크므로 SQLBindCol 대신 SQLGetData를 사용하여 처리하는 것이 일반적입니다. 서버 커서를 사용할 경우 행 인출 시 바인딩되지 않은 text, ntext 또는 image 열에 대한 데이터는 전송하지 않도록 SQL Server Native Client ODBC 드라이버가 최적화되어 있습니다. text, ntext 또는 image 데이터는 응용 프로그램이 해당 열에 대해 SQLGetData를 실행할 때까지 서버에서 검색되지 않습니다.

이와 같은 최적화를 응용 프로그램에 적용하여 사용자가 커서를 위나 아래로 스크롤하는 동안 text, ntext 또는 image 데이터를 표시하지 않도록 할 수 있습니다. 이 경우 사용자가 행을 선택한 후에만 응용 프로그램이 SQLGetData를 호출하여 text, ntext 또는 image 데이터를 검색할 수 있습니다. 사용자가 선택하지 않은 행에 대해서는 text, ntext 또는 image 데이터가 전송되지 않으므로 많은 양의 데이터가 불필요하게 전송되는 것을 방지할 수 있습니다.

참고 항목

개념