无法使用SQLDescribeCol()/ SQLBindCol()获取查询结果

时间:2018-05-08 12:46:07

标签: database odbc

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,这是唯一可以这样做的技术。

1 个答案:

答案 0 :(得分:0)

SQLWCHAR *owner = NULL;
...
SQLBindCol( stmt, 1, SQL_C_WCHAR, &owner, columnSizePtr, &cbTableOwner );

您正在给出指针的地址,因此指针本身会被覆盖。