简体   繁体   English

mySQL 返回 NO_DATA,但记录存在

[英]mySQL return NO_DATA, but record exists

Trying to run the following尝试运行以下

std::wstring query1 = L"SELECT st.table_id FROM information_schema.INNODB_TABLES st  WHERE st.name = ?;";

or要么

std::wstring query1 = L"SELECT st.table_id FROM information_schema.INNODB_TABLES st  WHERE st.name = CONCAT(?, '/', ?);";

returns SQL_NO_DATA , but if the parameter is spelled out the record is returned.返回SQL_NO_DATA ,但如果拼写出参数,则返回记录。

Code is as follows:代码如下:

auto res1 = mysql_stmt_init( m_db );
if( !res1 )
{
    std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res1 ) );
    errors.push_back( err );
    result = 1;
}
else
{
    if( mysql_stmt_prepare( res1, m_pimpl->m_myconv.to_bytes( query1.c_str() ).c_str(), query1.length() ) )
    {
        std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res1 ) );
        errors.push_back( err );
        result = 1;
    }
    else
    {
        MYSQL_BIND params[2];
        unsigned long str_length1, str_length2;
        str_length1 = strlen( m_pimpl->m_myconv.to_bytes( schema.c_str() ) .c_str() ) * 2;
        str_length2 = strlen( m_pimpl->m_myconv.to_bytes( table.c_str() ).c_str() ) * 2;
        char *str_data1 = new char[str_length1], *str_data2 = new char[str_length2];
        memset( str_data1, '\0', str_length1 );
        memset( str_data2, '\0', str_length2 );
        memset( params, 0, sizeof( params ) );
        strncpy( str_data1, m_pimpl->m_myconv.to_bytes( schema.c_str() ) .c_str(), str_length1 );
        strncpy( str_data2, m_pimpl->m_myconv.to_bytes( table.c_str() ).c_str(), str_length2 );
        params[0].buffer_type = MYSQL_TYPE_STRING;
        params[0].buffer = (char *) str_data1;
        params[0].buffer_length = strlen( str_data1 );
        params[0].is_null = 0;
        params[0].length = &str_length1;
        params[1].buffer_type = MYSQL_TYPE_STRING;
        params[1].buffer = (char *) str_data2;
        params[1].buffer_length = strlen( str_data2 );
        params[1].is_null = 0;
        params[1].length = &str_length2;
        if( mysql_stmt_bind_param( res1, params ) )
        {
            std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res1 ) );
            errors.push_back( err );
            result = 1;
        }
        else
        {
            auto prepare_meta_result = mysql_stmt_result_metadata( res1 );
            if( !prepare_meta_result )
            {
                std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res1 ) );
                errors.push_back( err );
                result = 1;
            }
            else
            {
                if( mysql_stmt_execute( res1 ) )
                {
                    std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res1 ) );
                    errors.push_back( err );
                    result = 1;
                }
                else
                {
                    MYSQL_BIND results1[1];
                    bool is_null[1], error[1];
                    unsigned long length[1];
                    memset( results1, 0, sizeof( results1 ) );
                    results1[0].buffer_type = MYSQL_TYPE_LONG;
                    
                    results1[0].buffer = (char *) &tableId;
                    results1[0].is_null = &is_null[1];
                    results1[0].error = &error[1];
                    results1[0].length = &length[1];
                    
                    if( mysql_stmt_bind_result( res1, results1 ) )
                    {
                        std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res1 ) );
                        errors.push_back( err );
                        result = 1;
                    }
                    else
                    {
                        while( true )
                        {
                            auto dataset = mysql_stmt_fetch( res1 );
                            if( dataset == 1 || dataset == MYSQL_NO_DATA )
                                break;
                            else
                                id = tableId;
                        }
                        mysql_free_result( prepare_meta_result );
                    }
                }
            }
        }
    }
}
if( mysql_stmt_close( res1 ) )
{
    std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res1 ) );
    errors.push_back( err );
    result = 1;
}

What am I missing?我错过了什么?

I suspect you have a lifetime issue.我怀疑你有一个终身问题。 Consider the following code:考虑以下代码:

{
    if( mysql_stmt_prepare( res1, m_pimpl->m_myconv.to_bytes( query1.c_str() ).c_str(), query1.length() ) )
    {

You take your wstring query1 (and WHY is it a wstring if you need it to be a std::string???), and pass it to m_pimpl->m_myconv.to_bytes .你拿你的wstring query1 (如果你需要它是一个 std::string,为什么它是一个 wstring???),并将它传递给m_pimpl->m_myconv.to_bytes I assume that function does the Unicode-to-ANSI translation and returns a std::string .我假设该函数执行 Unicode 到 ANSI 的转换并返回一个std::string You then call c_str() on that to get a buffer, and pass that to mysql_stmt_prepare .然后调用c_str()以获得缓冲区,并将其传递给mysql_stmt_prepare

HOWEVER, what to_bytes returns is a temporary.但是, to_bytes返回的是临时的。 As soon as the if statement exits, that string goes out of scope and will be destroyed, leaving the statement holding a pointer into nothing.一旦if语句退出,该字符串就会超出范围并被销毁,留下一个指向空指针的语句。 I suggest you try:我建议你试试:

    std::string query1s = m_pimpl->m_myconv.to_bytes( query1.c_str() );
    if( mysql_stmt_prepare( res1, query1s.c_str(), query1s.length() ) )
    {

This has the additional benefit of letting you print the value of query1s to make sure it matches your expectation.这样做的额外好处是让您打印query1s的值以确保它符合您的期望。

Now, IF mysql_stmt_prepare actually copies the input string, instead of just grabbing a pointer, then this won't fix anything.现在,如果mysql_stmt_prepare实际上复制了输入字符串,而不是仅仅获取一个指针,那么这不会解决任何问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM