在具有疏鬆資料行的資料表上呼叫 SQLColumns
此範例會示範如何在已使用 SQL Server Native Client 中之 ODBC 定義疏鬆資料行的資料表上呼叫 SQLColumns。
此範例不適用於 SQL Server 2008 之前的任何 SQL Server 版本。
如需有關疏鬆資料行功能的詳細資訊,請參閱<SQL Server Native Client 中的疏鬆資料行支援>。
範例
第一個清單是 C++ 原始程式碼。 請將 "MyServer" 變更為有效的伺服器名稱。 請確認您的 INCLUDE 環境變數包含的目錄內含 sqlncli.h。 如果您要建立並執行此範例,當做 64 位元作業系統上的 32 位元應用程式,您必須利用 %windir%\SysWOW64\odbcad32.exe,以 ODBC 管理員身分建立 ODBC 資料來源。
這個範例會連接到電腦的預設 SQL Server 執行個體。 若要連接到具名執行個體,請變更 ODBC 資料來源的定義,以便使用下列格式指定執行個體:server\namedinstance。 根據預設,SQL Server Express 會安裝至具名執行個體。
使用 /EHsc /D、"UNICODE" 和 odbc32.lib 編譯。
第二個 (Transact-SQL) 程式碼清單會刪除此範例所建立的資料表。
// compile with: /EHsc /D "UNICODE" odbc32.lib
#include <windows.h>
#include <stdio.h>
#include <sqlext.h>
#include <sqlncli.h>
#define SUCCESS(x) (!((x) & 0xFFFE))
#define CHKRC(stmt) rc = (stmt); \
if (!SUCCESS(rc)) \
throw (RETCODE) rc;
void PrintError(SQLSMALLINT HandleType, SQLHANDLE Handle) {
RETCODE rc = SQL_SUCCESS;
SQLTCHAR szSqlState[6], szMessage[1024];
SQLSMALLINT i = 1, msgLen = 0;
SQLINTEGER NativeError;
do {
i = 1;
while (SQL_NO_DATA != (rc = SQLGetDiagRec(HandleType, Handle, i, szSqlState, &NativeError,
szMessage, sizeof(szMessage)/sizeof(SQLTCHAR), &msgLen)) && SUCCESS(rc)) {
wprintf(L"SQLState=%s, NativeError=%ld, Message=%s\r\n", szSqlState, NativeError, szMessage);
i++;
}
}
while (SQL_NO_DATA != (rc = SQLMoreResults(Handle)) && SUCCESS(rc));
}
#define STR_LEN 128 + 1
#define REM_LEN 254 + 1
void ProcessSQLColumnsResult(SQLHSTMT hstmt) {
SQLCHAR szSchema[STR_LEN];
SQLCHAR szCatalog[STR_LEN];
SQLCHAR szColumnName[STR_LEN];
SQLCHAR szTableName[STR_LEN];
SQLCHAR szTypeName[STR_LEN];
SQLCHAR szRemarks[REM_LEN];
SQLCHAR szColumnDefault[STR_LEN];
SQLCHAR szIsNullable[STR_LEN];
SQLINTEGER ColumnSize;
SQLINTEGER BufferLength;
SQLINTEGER CharOctetLength;
SQLINTEGER OrdinalPosition;
SQLSMALLINT DataType;
SQLSMALLINT DecimalDigits;
SQLSMALLINT NumPrecRadix;
SQLSMALLINT Nullable;
SQLSMALLINT SQLDataType;
SQLSMALLINT DatetimeSubtypeCode;
SQLLEN cbCatalog;
SQLLEN cbSchema;
SQLLEN cbTableName;
SQLLEN cbColumnName;
SQLLEN cbDataType;
SQLLEN cbTypeName;
SQLLEN cbColumnSize;
SQLLEN cbBufferLength;
SQLLEN cbDecimalDigits;
SQLLEN cbNumPrecRadix;
SQLLEN cbNullable;
SQLLEN cbRemarks;
SQLLEN cbColumnDefault;
SQLLEN cbSQLDataType;
SQLLEN cbDatetimeSubtypeCode;
SQLLEN cbCharOctetLength;
SQLLEN cbOrdinalPosition;
SQLLEN cbIsNullable;
SQLRETURN rc = SQL_SUCCESS;
CHKRC(SQLColumns(hstmt, L"tempdb", SQL_NTS, L"dbo", SQL_NTS, L"tbl_sparse_test", SQL_NTS, NULL, 0 ));
// Bind columns in result set to buffers
SQLBindCol(hstmt, 1, SQL_C_CHAR, szCatalog, STR_LEN, &cbCatalog);
SQLBindCol(hstmt, 2, SQL_C_CHAR, szSchema, STR_LEN, &cbSchema);
SQLBindCol(hstmt, 3, SQL_C_CHAR, szTableName, STR_LEN, &cbTableName);
SQLBindCol(hstmt, 4, SQL_C_CHAR, szColumnName, STR_LEN, &cbColumnName);
SQLBindCol(hstmt, 5, SQL_C_SSHORT, &DataType, 0, &cbDataType);
SQLBindCol(hstmt, 6, SQL_C_CHAR, szTypeName, STR_LEN, &cbTypeName);
SQLBindCol(hstmt, 7, SQL_C_SLONG, &ColumnSize, 0, &cbColumnSize);
SQLBindCol(hstmt, 8, SQL_C_SLONG, &BufferLength, 0, &cbBufferLength);
SQLBindCol(hstmt, 9, SQL_C_SSHORT, &DecimalDigits, 0, &cbDecimalDigits);
SQLBindCol(hstmt, 10, SQL_C_SSHORT, &NumPrecRadix, 0, &cbNumPrecRadix);
SQLBindCol(hstmt, 11, SQL_C_SSHORT, &Nullable, 0, &cbNullable);
SQLBindCol(hstmt, 12, SQL_C_CHAR, szRemarks, REM_LEN, &cbRemarks);
SQLBindCol(hstmt, 13, SQL_C_CHAR, szColumnDefault, STR_LEN, &cbColumnDefault);
SQLBindCol(hstmt, 14, SQL_C_SSHORT, &SQLDataType, 0, &cbSQLDataType);
SQLBindCol(hstmt, 15, SQL_C_SSHORT, &DatetimeSubtypeCode, 0, &cbDatetimeSubtypeCode);
SQLBindCol(hstmt, 16, SQL_C_SLONG, &CharOctetLength, 0, &cbCharOctetLength);
SQLBindCol(hstmt, 17, SQL_C_SLONG, &OrdinalPosition, 0, &cbOrdinalPosition);
SQLBindCol(hstmt, 18, SQL_C_CHAR, szIsNullable, STR_LEN, &cbIsNullable);
try {
while (SQL_SUCCESS == rc) {
CHKRC(SQLFetch(hstmt));
wprintf(L"Column name: %hs\tIsNullable: %hs\tType: %hs\n", szColumnName, szIsNullable, szTypeName);
}
}
catch (RETCODE retcode) {
if (SQL_NO_DATA != retcode)
throw retcode;
}
SQLFreeStmt(hstmt, SQL_CLOSE);
}
int main() {
RETCODE rc = SQL_SUCCESS;
HENV henv = SQL_NULL_HENV;
HDBC hdbc = SQL_NULL_HDBC;
SQLHSTMT hstmt = SQL_NULL_HSTMT;
SQLTCHAR * pszConnection = L"DRIVER={SQL Server Native Client 10.0}; Server=MyServer; Trusted_Connection=Yes;";
try {
CHKRC(SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HENV, &henv));
CHKRC(SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0));
CHKRC(SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc));
CHKRC(SQLDriverConnect( hdbc, NULL, pszConnection, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT));
CHKRC(SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt));
CHKRC(SQLExecDirect(hstmt,
L"if object_id('tempdb.dbo.tbl_sparse_test','U') is not null drop table tempdb.dbo.tbl_sparse_test",
SQL_NTS));
// Create a new table
CHKRC(SQLExecDirect(hstmt,
L"create table tempdb.dbo.tbl_sparse_test (col1 int SPARSE, col2 int, col3 XML column_set for all_sparse_columns)",
SQL_NTS));
// Insert a row into the table
CHKRC(SQLExecDirect(hstmt,
L"insert tempdb.dbo.tbl_sparse_test (col1, col2) values (1,2)",
SQL_NTS));
wprintf(L"Checking default SQLColumns behavior.\nYou should not see the first sparse column.\n");
ProcessSQLColumnsResult(hstmt);
wprintf(L"\nChecking SQLColumns with the statement attribute SQL_SS_NAME_SCOPE_EXTENDED.\nYou should see all the columns\n");
CHKRC(SQLSetStmtAttr(hstmt, SQL_SOPT_SS_NAME_SCOPE, (SQLPOINTER)SQL_SS_NAME_SCOPE_EXTENDED, SQL_IS_SMALLINT));
ProcessSQLColumnsResult(hstmt);
wprintf(L"\nChecking SQLColumns with the statement attribute SQL_SS_NAME_SCOPE_SPARSE_COLUMN_SET.\nYou should see only the sparse columns\n");
CHKRC(SQLSetStmtAttr(hstmt, SQL_SOPT_SS_NAME_SCOPE, (SQLPOINTER)SQL_SS_NAME_SCOPE_SPARSE_COLUMN_SET, SQL_IS_SMALLINT));
ProcessSQLColumnsResult(hstmt);
}
catch (RETCODE retcode) {
rc = retcode;
}
if (!SUCCESS(rc)) {
if (hstmt)
PrintError(SQL_HANDLE_STMT, hstmt);
else if (hdbc)
PrintError(SQL_HANDLE_DBC, hdbc);
else if(henv)
PrintError(SQL_HANDLE_ENV, henv);
}
if (hstmt)
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
if (hdbc) {
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
}
if (henv)
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
use tempdb
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'tbl_sparse_test')
DROP TABLE tbl_sparse_test
GO