SQLTables 函数

一致性
引入的版本:ODBC 1.0 标准符合性:开放组

摘要
SQLTables 返回存储在特定数据源中的表、目录或架构名称和表类型的列表。 驱动程序以结果集的形式返回信息。

语法

  
SQLRETURN SQLTables(  
     SQLHSTMT       StatementHandle,  
     SQLCHAR *      CatalogName,  
     SQLSMALLINT    NameLength1,  
     SQLCHAR *      SchemaName,  
     SQLSMALLINT    NameLength2,  
     SQLCHAR *      TableName,  
     SQLSMALLINT    NameLength3,  
     SQLCHAR *      TableType,  
     SQLSMALLINT    NameLength4);  

参数

StatementHandle
[输入]检索结果的语句句柄。

CatalogName
[输入]目录名称。 如果SQL_ODBC_VERSION环境属性SQL_OV_ODBC3, CatalogName 参数接受搜索模式;如果设置了SQL_OV_ODBC2,则它不接受搜索模式。 如果驱动程序支持某些表的目录,但不支持其他表,例如,当驱动程序从不同的 DBMS 检索数据时,空字符串 (“”) 指示没有目录的表。

如果 SQL_ATTR_METADATA_ID 语句属性设置为SQL_TRUE, 则 CatalogName 被视为标识符,并且其大小写并不重要。 如果SQL_FALSE, CatalogName 是模式值参数;它按字面处理,其大小写非常重要。 有关详细信息,请参阅 目录函数中的参数

NameLength1
[输入]*CatalogName 的长度(以字符为单位)。

SchemaName
[输入]架构名称的字符串搜索模式。 如果驱动程序支持某些表的架构,但不支持其他表,例如,当驱动程序从不同的 DBMS 检索数据时,空字符串 (“”) 指示没有架构的表。

如果SQL_ATTR_METADATA_ID语句属性设置为SQL_TRUE, 则 SchemaName 被视为标识符,并且其大小写并不重要。 如果SQL_FALSE, SchemaName 是模式值参数;它按字面处理,其大小写非常重要。

NameLength2
[输入]*SchemaName 的长度(以字符为单位)。

TableName
[输入]表名称的字符串搜索模式。

如果 SQL_ATTR_METADATA_ID 语句属性设置为SQL_TRUE, 则 TableName 被视为标识符,并且其大小写并不重要。 如果SQL_FALSE, TableName 是模式值参数;它按字面处理,其大小写非常重要。

NameLength3
[输入]*TableName 的长度(以字符为单位)。

TableType
[输入]要匹配的表类型列表。

请注意,SQL_ATTR_METADATA_ID语句属性对 TableType 参数没有影响。 TableType 是值列表参数,无论SQL_ATTR_METADATA_ID的设置如何。

NameLength4
[输入]*TableType 字符的长度。

返回

SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、SQL_STILL_EXECUTING、SQL_ERROR或SQL_INVALID_HANDLE。

诊断

SQLTables 返回SQL_ERROR或SQL_SUCCESS_WITH_INFO时,可以通过使用 handleType of SQL_HANDLE_STMT 和 Handle ofStatementHandle 调用 SQLGetDiagRec 来获取关联的 SQLSTATE 值。 下表列出了 SQLTable 通常返回的 SQLSTATE 值,并在此函数的上下文中解释每个值:表示法“ (DM) ”位于驱动程序管理器返回的 SQLSTATE 的说明之前。 与每个 SQLSTATE 值关联的返回代码SQL_ERROR,除非另有说明。

SQLSTATE 错误 说明
01000 常规警告 特定于驱动程序的信息性消息。 (函数返回 SQL_SUCCESS_WITH_INFO.)
08S01 通信链接失败 驱动程序与驱动程序连接到的数据源之间的通信链接在函数完成处理之前失败。
24000 游标状态无效 在 StatementHandle 上打开了游标,并调用了 SQLFetchSQLFetchScroll。 如果 SQLFetch 或SQLFetchScroll 未返回SQL_NO_DATA,并且如果 SQLFetch 或 SQLFetchScroll 返回SQL_NO_DATA,则驱动程序将返回此错误。

语句Handle 上打开了游标,但未调用 SQLFetchSQLFetchScroll
40001 序列化失败 由于与另一个事务发生资源死锁,事务已回滚。
40003 语句完成未知 执行此函数期间关联的连接失败,无法确定事务的状态。
HY000 常规错误 发生错误:没有特定的 SQLSTATE,也没有定义特定于实现的 SQLSTATE。 *MessageText 缓冲区中 SQLGetDiagRec 返回的错误消息描述错误及其原因。
HY001 内存分配错误 驱动程序无法分配支持执行或完成函数所需的内存。
HY008 操作已取消 StatementHandle 启用了异步处理。 调用函数,并在完成执行之前,SQLCancel 或 SQLCancelHandleStatementHandle 上调用。 然后,在 StatementHandle 上再次调用该函数。

调用函数,并在完成执行之前,SQLCancel 或 SQLCancelHandle 从多线程应用程序中的不同线程调用 StatementHandle
HY009 无效使用 null 指针 SQL_ATTR_METADATA_ID语句属性设置为SQL_TRUE, CatalogName 参数为空指针,SQL_CATALOG_NAME InfoType 返回支持目录名称。

(DM) SQL_ATTR_METADATA_ID 语句属性设置为SQL_TRUE, SchemaNameTableName 参数为空指针。
HY010 函数序列错误 (DM) 为与 StatementHandle 关联的连接句柄调用异步执行函数。 调用 SQLTable 时,此异步函数仍在执行。

(DM) SQLExecute、SQLExecDirectSQLMoreResults 已针对 StatementHandle 调用并返回SQL_PARAM_DATA_AVAILABLE。 在检索所有流式处理参数的数据之前调用此函数。

(DM) 异步执行的函数 (不是为 StatementHandle 调用此函数) ,并且调用此函数时仍在执行。

(DM) SQLExecuteSQLExecDirectSQLBulkOperationsSQLSetPos 已针对 StatementHandle 调用并返回SQL_NEED_DATA。 在为所有数据执行参数或列发送数据之前调用此函数。
HY013 内存管理错误 无法处理函数调用,因为基础内存对象无法访问,可能是由于内存条件低。
HY090 字符串或缓冲区长度无效 (DM) 长度参数之一的值小于 0,但不等于SQL_NTS。

名称长度参数之一的值超过了相应名称的最大长度值。
HY117 由于未知事务状态,连接暂停。 仅允许断开连接和只读函数。 (DM) 有关挂起状态的详细信息,请参阅 SQLEndTran 函数
HYC00 未实现可选功能 指定了目录,驱动程序或数据源不支持目录。

指定了架构,驱动程序或数据源不支持架构。

为目录名称、表架构或表名指定了字符串搜索模式,数据源不支持一个或多个这些参数的搜索模式。

驱动程序或数据源不支持SQL_ATTR_CONCURRENCY和SQL_ATTR_CURSOR_TYPE语句属性的当前设置的组合。

SQL_ATTR_USE_BOOKMARKS语句属性设置为SQL_UB_VARIABLE,SQL_ATTR_CURSOR_TYPE语句属性设置为驱动程序不支持书签的游标类型。
HYT00 超时时间已到 在数据源返回请求的结果集之前,查询超时期限已过期。 超时期限通过 SQLSetStmtAttr 设置,SQL_ATTR_QUERY_TIMEOUT。
HYT01 超过连接超时时间 在数据源响应请求之前,连接超时期限已过期。 连接超时期限通过 SQLSetConnectAttr 设置,SQL_ATTR_CONNECTION_TIMEOUT。
IM001 驱动程序不支持此函数 (DM) 与 StatementHandle 关联的驱动程序不支持该函数。
IM017 在异步通知模式下禁用轮询 每当使用通知模型时,将禁用轮询。
IM018 尚未调用 SQLCompleteAsync 以完成此句柄上的上一个异步操作。 如果对句柄的上一个函数调用返回SQL_STILL_EXECUTING并且已启用通知模式,则必须在句柄上调用 SQLCompleteAsync 才能执行后期处理并完成操作。

注释

SQLTables 列出请求范围中的所有表。 用户可能或可能拥有对这些表中的任何一个表的 SELECT 权限。 若要检查辅助功能,应用程序可以:

  • 调用 SQLGetInfo 并检查SQL_ACCESSIBLE_TABLES信息类型。

  • 调用 SQLTablePrivileges 以检查每个表的权限。

否则,应用程序必须能够处理用户选择不授予 SELECT 权限的表的情况。

SchemaNameTableName 参数接受搜索模式。 如果SQL_ODBC_VERSION环境属性SQL_OV_ODBC3, CatalogName 参数接受搜索模式;如果设置了SQL_OV_ODBC2,则不接受搜索模式。 如果设置了SQL_OV_ODBC3,ODBC 3*.x* 驱动程序将要求对 CatalogName 参数中的通配符进行转义以字面处理。 有关有效搜索模式的详细信息,请参阅 模式值参数

备注

有关 ODBC 目录函数的常规用途、参数和返回数据的详细信息,请参阅 目录函数

为了支持目录、架构和表类型的枚举,为 SQLTableCatalogNameSchemaName、TableNameTableType 参数定义了以下特殊语义:

  • 如果 CatalogName SQL_ALL_CATALOGS且 SchemaNameTableName 为空字符串,则结果集包含数据源的有效目录列表。 (除TABLE_CAT列以外的所有列都包含 NULLs.)

  • 如果 SchemaName 为SQL_ALL_SCHEMAS且 CatalogNameTableName 为空字符串,则结果集包含数据源的有效架构列表。 (除TABLE_SCHEM列以外的所有列都包含 NULL.)

  • 如果 TableType SQL_ALL_TABLE_TYPES且 CatalogNameSchemaNameTableName 为空字符串,则结果集包含数据源的有效表类型列表。 (除TABLE_TYPE列以外的所有列都包含 NULLs.)

如果 TableType 不是空字符串,则它必须包含感兴趣的类型的逗号分隔值列表;每个值可以用单引号括起来, (') 或无引号,例如“TABLE”、“VIEW”或 TABLE、VIEW。 应用程序应始终以大写形式指定表类型;驱动程序应将表类型转换为数据源所需的任何情况。 如果数据源不支持指定的表类型, SQLTables 不会返回该类型的任何结果。

SQLTables 以标准结果集的形式返回结果,按TABLE_TYPE、TABLE_CAT、TABLE_SCHEM和TABLE_NAME排序。 有关如何使用此信息的信息,请参阅 目录数据的用法

若要确定TABLE_CAT、TABLE_SCHEM和TABLE_NAME列的实际长度,应用程序可以使用SQL_MAX_CATALOG_NAME_LEN、SQL_MAX_SCHEMA_NAME_LEN和SQL_MAX_TABLE_NAME_LEN信息类型调用 SQLGetInfo

已为 ODBC 3*.x* 重命名以下列。 列名更改不会影响向后兼容性,因为应用程序按列号绑定。

ODBC 2.0 列 ODBC 3*.x* 列
TABLE_QUALIFIER TABLE_CAT
TABLE_OWNER TABLE_SCHEM

下表列出了结果集中的列。 驱动程序可以定义超出第 5 列 (备注) 的其他列。 应用程序应从结果集的末尾倒数,而不是指定显式序号位置来访问特定于驱动程序的列。 有关详细信息,请参阅 目录函数返回的数据

列名称 列号 数据类型 注释
TABLE_CAT (ODBC 1.0) 1 Varchar 目录名称;如果不适用于数据源,则为 NULL。 如果驱动程序支持某些表的目录,但不支持其他表,例如当驱动程序从不同的 DBMS 检索数据时,它将返回空字符串 (“”) 那些没有目录的表。
TABLE_SCHEM (ODBC 1.0) 2 Varchar 架构名称;如果不适用于数据源,则为 NULL。 如果驱动程序支持某些表的架构,但不支持其他表,例如驱动程序从不同的 DBMS 检索数据时,它将返回空字符串 (“”) 那些没有架构的表。
TABLE_NAME (ODBC 1.0) 3 Varchar 表名。
TABLE_TYPE (ODBC 1.0) 4 Varchar 表类型名称;下列选项之一:“TABLE”、“VIEW”、“SYSTEM TABLE”、“GLOBAL TEMPORARY”、“LOCAL TEMPORARY”、“ALIAS”、“SYNONYM”或数据源特定的类型名称。

“ALIAS”和“SYNONYM”的含义特定于驱动程序。
(ODBC 1.0) 备注 5 Varchar 表的说明。

示例

以下示例代码不释放句柄和连接。 有关代码示例来释放句柄和语句,请参阅 SQLFreeHandle 函数SQLFreeStmt 函数

// SQLTables.cpp  
// compile with: user32.lib odbc32.lib  
#include <windows.h>  
#include <sqlext.h>  
#include <strsafe.h>  
  
// simple helper functions  
int MySQLSuccess(SQLRETURN rc) {  
   return (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO);  
}  
  
struct DataBinding {  
   SQLSMALLINT TargetType;  
   SQLPOINTER TargetValuePtr;  
   SQLINTEGER BufferLength;  
   SQLLEN StrLen_or_Ind;  
};  
  
void printCatalog(const struct DataBinding* catalogResult) {  
   if (catalogResult[0].StrLen_or_Ind != SQL_NULL_DATA)   
      printf("Catalog Name = %s\n", (char *)catalogResult[0].TargetValuePtr);  
}  
  
// remember to disconnect and free memory, and free statements and handles  
int main() {  
   int bufferSize = 1024, i, numCols = 5;  
   struct DataBinding* catalogResult = (struct DataBinding*) malloc( numCols * sizeof(struct DataBinding) );  
   wchar_t* dbName = (wchar_t *)malloc( sizeof(wchar_t)*bufferSize );  
   wchar_t* userName = (wchar_t *)malloc( sizeof(wchar_t)*bufferSize );  
  
   // declare and initialize the environment, connection, statement handles  
   SQLHENV henv = NULL;   // Environment     
   SQLHDBC hdbc = NULL;   // Connection handle  
   SQLHSTMT hstmt = NULL;   // Statement handle  
  
   SQLRETURN retCode;  
   HWND desktopHandle = GetDesktopWindow();   // desktop's window handle  
   SQLWCHAR connStrbuffer[1024];  
   SQLSMALLINT connStrBufferLen;  
  
   retCode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);  
   retCode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, -1);  
   retCode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);  
   retCode = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)10, 0);  
   retCode = SQLDriverConnect(hdbc, desktopHandle, (SQLCHAR*)"Driver={SQL Server}", SQL_NTS, (SQLCHAR*)connStrbuffer, 1024 + 1, &connStrBufferLen, SQL_DRIVER_PROMPT);  
   retCode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);  
   retCode = SQLGetInfo(hdbc, SQL_DATABASE_NAME, dbName, (SQLSMALLINT)bufferSize, (SQLSMALLINT *)&bufferSize);  
   retCode = SQLGetInfo(hdbc, SQL_USER_NAME, userName, (SQLSMALLINT)bufferSize, (SQLSMALLINT *)&bufferSize);  
  
   bufferSize = 1024;  
  
   // allocate memory for the binding  
   // free this memory when done  
   for ( i = 0 ; i < numCols ; i++ ) {  
      catalogResult[i].TargetType = SQL_C_CHAR;  
      catalogResult[i].BufferLength = (bufferSize + 1);  
      catalogResult[i].TargetValuePtr = malloc( sizeof(unsigned char)*catalogResult[i].BufferLength );  
   }  
  
   // setup the binding (can be used even if the statement is closed by closeStatementHandle)  
   for ( i = 0 ; i < numCols ; i++ )  
      retCode = SQLBindCol(hstmt, (SQLUSMALLINT)i + 1, catalogResult[i].TargetType, catalogResult[i].TargetValuePtr, catalogResult[i].BufferLength, &(catalogResult[i].StrLen_or_Ind));  
  
   // all catalogs query  
   printf( "A list of names of all catalogs\n" );  
   retCode = SQLTables( hstmt, (SQLCHAR*)SQL_ALL_CATALOGS, SQL_NTS, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS );  
   for ( retCode = SQLFetch(hstmt) ;  MySQLSuccess(retCode) ; retCode = SQLFetch(hstmt) )  
      printCatalog( catalogResult );  
}  
有关以下方面的信息 请参阅
将缓冲区绑定到结果集中的列 SQLBindCol 函数
取消语句处理 SQLCancel 函数
返回列或列的权限 SQLColumnPrivileges 函数
返回表或表中的列 SQLColumns 函数
提取单行或仅向前方向的数据块 SQLFetch 函数
提取数据块或滚动结果集 SQLFetchScroll Function(SQLFetchScroll 函数)
返回表统计信息和索引 SQLStatistics 函数
返回表或表的权限 SQLTablePrivileges Function(SQLTablePrivileges 函数)

另请参阅

ODBC API 参考
ODBC 头文件