mysql_stmt_execute上的奇怪错误

时间:2017-10-23 05:13:15

标签: c++ mysql

尝试执行mysql_stmt_execute时出现了一个奇怪的错误。

流程如下:

  1. 我得到了我正在连接的数据库中的表列表。 (目录,架构和名称)
  2. 对于每个表,我都会获得外键,字段和索引列表。
  3. 在我点击名为performance_schema.events_stages_summary_by_account_by_event_name的表格之前,一切顺利。

    我收到错误:Identifier name "events_stages_summary_by_account_by_event_name" is too long。奇怪的是,名称不是标识符 - 它是查询的参数,它小于64个字符,这是标识符限制。

    以下是相关代码:

    std::wstring query3 = L"SELECT kcu.column_name, kcu.ordinal_position, kcu.referenced_table_schema, kcu.referenced_table_name, kcu.referenced_column_name, rc.update_rule, rc.delete_rule FROM information_schema.key_column_usage kcu, information_schema.referential_constraints rc WHERE kcu.constraint_name = rc.constraint_name AND kcu.table_catalog = ? AND kcu.table_schema = ? AND kcu.table_name = ?;";
    char *catalog_name = row[0] ? row[0] : NULL;
    char *schema_name = row[1] ? row[1] : NULL;
    char *table_name = row[2] ? row[2] : NULL;
    MYSQL_BIND params[3];
    unsigned long str_length1, str_length2, str_length3;
    str_length1 = strlen( catalog_name ) * 2;
    str_length2 = strlen( schema_name ) * 2;
    str_length3 = strlen( table_name ) * 2;
    str_data1 = new char[str_length1], str_data2 = new char[str_length2], str_data3 = new char[str_length3];
    memset( str_data1, '\0', str_length1 );
    memset( str_data2, '\0', str_length2 );
    memset( str_data3, '\0', str_length3 );
    memset( params, 0, sizeof( params ) );
    strncpy( str_data1, catalog_name, str_length1 );
    strncpy( str_data2, schema_name, str_length2 );
    strncpy( str_data3, table_name, str_length3 );
    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;
    params[2].buffer_type = MYSQL_TYPE_STRING;
    params[2].buffer = (char *) str_data3;
    params[2].buffer_length = strlen( str_data3 );
    params[2].is_null = 0;
    params[2].length = &str_length3;
    if( mysql_stmt_bind_param( res1, params ) )
    {
    std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res1 ) );
    errorMsg.push_back( err );
    result = 1;
    break;
    }
    else
    {
    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 ) );
    errorMsg.push_back( err );
    result = 1;
    break;
    }
    else
    {
    if( mysql_stmt_execute( res1 ) )
    {
    std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res1 ) );
    errorMsg.push_back( err );
    result = 1;
    break;
    }
    

    有人可以对这个错误有所了解吗?我可以尝试跳过这张表,但我不愿意。

    [编辑]

    mysql --version
    mysql ver 14.14 Distrib 5.6.35, for Linux (x86+64) using Editine wrapper
    

    [/编辑]

1 个答案:

答案 0 :(得分:0)

修改 似乎代码确实没问题,strncpy就可以了。我错误地认为分配的长度是字符串长度的两倍,但长度仍然只是字符串的一个长度。

您看到该错误的原因是您使用的字符串非空终止。这是因为如果strncpy超过给定限制并且您使用的限制是字符串的实际长度,则memset( str_data1, '\0', str_length1 ); strncpy( str_data1, catalog_name, str_length1 ); params[0].buffer_length = strlen( str_data1 ); 不会对字符串进行空终止:

const char*

更好的方法是使用null {终止字符串'的snprintf(3)或使用@ID varchar = ‘1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20’ 和长度作为参数的std::string constructor

<击>