int ODBCDatabase::GetTableOwner(const std::wstring &schemaName, const std::wstring &tableName, std::wstring &tableOwner, std::vector<std::wstring> &errorMsg)
{
SQLHSTMT stmt = 0;
SQLHDBC hdbc = 0;
int result = 0;
SQLLEN cbTableName = SQL_NTS, cbSchemaName = SQL_NTS;
SQLWCHAR *table_name = NULL, *schema_name = NULL, *qry = NULL;
SQLWCHAR *owner = NULL;
std::wstring query;
if( pimpl->m_subtype == L"Microsoft SQL Server" )
query = L"SELECT cast(su.name AS nvarchar(128)) FROM sysobjects so, sysusers su, sys.tables t, sys.schemas s WHERE so.uid = su.uid AND t.object_id = so.id AND t.schema_id = s.schema_id AND s.name = ? AND so.name = ?;";
SQLRETURN retcode = SQLAllocHandle( SQL_HANDLE_DBC, m_env, &hdbc );
if( retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
{
GetErrorMessage( errorMsg, 0 );
result = 1;
}
else
{
SQLSMALLINT OutConnStrLen;
retcode = SQLDriverConnect( hdbc, NULL, m_connectString, SQL_NTS, NULL, 0, &OutConnStrLen, SQL_DRIVER_NOPROMPT );
if( retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
{
GetErrorMessage( errorMsg, 2, hdbc );
result = 1;
}
else
{
retcode = SQLAllocHandle( SQL_HANDLE_STMT, hdbc, &stmt );
if( retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
{
GetErrorMessage( errorMsg, 2, hdbc );
result = 1;
}
else
{
table_name = new SQLWCHAR[tableName.length() + 2];
schema_name = new SQLWCHAR[schemaName.length() + 2];
qry = new SQLWCHAR[query.length() + 2];
memset( qry, '\0', query.size() + 2 );
memset( table_name, '\0', tableName.length() + 2 );
memset( schema_name, '\0', schemaName.length() + 2 );
uc_to_str_cpy( qry, query );
uc_to_str_cpy( table_name, tableName );
uc_to_str_cpy( schema_name, schemaName );
retcode = SQLPrepare( stmt, qry, SQL_NTS );
if( retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO )
{
retcode = SQLBindParameter( stmt, 1, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WCHAR, schemaName.length(), 0, schema_name, 0, &cbSchemaName );
if( retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO )
{
retcode = SQLBindParameter( stmt, 2, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WCHAR, tableName.length(), 0, table_name, 0, &cbTableName );
if( retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO )
{
retcode = SQLExecute( stmt );
if( retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO )
{
SQLSMALLINT nameBufLength, dataTypePtr, decimalDigitsPtr, isNullable;
SQLULEN columnSizePtr;
SQLLEN cbTableOwner;
retcode = SQLDescribeCol( stmt, 1, NULL, 0, &nameBufLength, &dataTypePtr, &columnSizePtr, &decimalDigitsPtr, &isNullable );
if( retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO )
{
owner = new SQLWCHAR[columnSizePtr + 1];
retcode = SQLBindCol( stmt, 1, SQL_C_WCHAR, &owner, columnSizePtr, &cbTableOwner );
if( retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO )
{
retcode = SQLFetch( stmt );
if( retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO && retcode != SQL_NO_DATA )
{
GetErrorMessage( errorMsg, 1, stmt );
result = 1;
}
if( retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO )
str_to_uc_cpy( tableOwner, owner );
}
else
{
if( pimpl->m_subtype == L"Microsoft SQL Server" )
{
tableOwner = L"dbo";
result = 0;
}
else
{
GetErrorMessage( errorMsg, 1, stmt );
result = 1;
}
}
}
else if( retcode != SQL_NO_DATA )
{
GetErrorMessage( errorMsg, 1, stmt );
result = 1;
}
}
else if( retcode != SQL_NO_DATA )
{
GetErrorMessage( errorMsg, 1, stmt );
result = 1;
}
}
else if( retcode != SQL_NO_DATA )
{
GetErrorMessage( errorMsg, 1, stmt );
result = 1;
}
}
else if( retcode != SQL_NO_DATA )
{
GetErrorMessage( errorMsg, 1, stmt );
result = 1;
}
}
else if( retcode != SQL_NO_DATA )
{
GetErrorMessage( errorMsg, 1, stmt );
result = 1;
}
}
}
}
if( stmt )
{
retcode = SQLFreeHandle( SQL_HANDLE_STMT, stmt );
if( retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
{
GetErrorMessage( errorMsg, 1, stmt );
result = 1;
}
else
{
stmt = 0;
retcode = SQLDisconnect( hdbc );
if( retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
{
GetErrorMessage( errorMsg, 1, stmt );
result = 1;
}
else
{
retcode = SQLFreeHandle( SQL_HANDLE_DBC, hdbc );
if( retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO )
{
GetErrorMessage( errorMsg, 1, stmt );
result = 1;
}
else
hdbc = 0;
}
}
}
delete qry;
qry = NULL;
delete table_name;
table_name = NULL;
delete schema_name;
schema_name = NULL;
delete owner;
owner = NULL;
return result;
}
上面的代码编译并执行正常。但是,即使SQLFetch()返回记录,数据也不可用。
有人能发现错误吗?这是我第一次使用SQDescribeCol()/ SQLBindCol()对,这里肯定是错的。
ODBC API的直接使用是因为该程序是跨平台/跨数据库的。 AFAIK,这是唯一可以这样做的技术。
答案 0 :(得分:0)
SQLWCHAR *owner = NULL;
...
SQLBindCol( stmt, 1, SQL_C_WCHAR, &owner, columnSizePtr, &cbTableOwner );
您正在给出指针的地址,因此指针本身会被覆盖。