对具有稀疏列的表调用 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