嵌入式MySQL中是否支持Prepared语句

时间:2012-03-29 17:50:59

标签: c++ mysql prepared-statement embedded-database

我通常使用实时服务器进行开发,但是我第一次想到了我是否会实现这一目标,看看我是否可以将所有(C ++)mysql代码作为嵌入式服务器运行。特别是,我非常喜欢准备好的陈述,因为他们(恕我直言)“通常”优于未准备好的品种。

我尝试过使用5.5.22中的libmysqld和5.6.4中的libmysqld,但都没有工作。

建立连接,简单的mysql_query / mysql_real_query命令工作正常,但是一旦我的第一个预处理语句发出mysql_stmt_fetch(),我就会得到讨厌的'命令不同步'错误。

一个非常类似的问题出现在oracles论坛(http://forums.mysql.com/read.php?168,507863,507863#msg-507863)而没有解决。

我没有看到,也不相信我错过了mysql_real_connect()和mysql_stmt_fetch()之间的任何命令。

对于使用预准备语句的嵌入式服务器的任何示例,我的所有搜索都是空的。我也没有找到一个实际的句子“你不能这样做”。

所以...是或不支持?

感谢您的专业知识。

//编辑 为了进一步揭开神秘面纱(并在必要时指示)我的完整mysql cmd序列如下:

mysql_library_init();  // as embedded
mysql_init();
mysql_options(MYSQL_SET_CHARSET_NAME);  //to utf8
mysql_options(MYSQL_OPT_USE_EMBEDDED_CONNECTION);
mysql_real_connect();
mysql_real_query("SET NAMES 'utf8'");
mysql_real_query("SET CHARACTER SET 'utf8'");
mysql_set_character_set("utf8");  // yes, you really do need to set utf8 four times
mysql_autocommit( mAutocommit ); 

此时,mysql_real_query()调用DO工作。我继续......

//all this would only happen once for each stmt
{
    mysql_stmt_init();
    mysql_stmt_prepare(theQuery);
    mysql_stmt_param_count(); // to assert input bind object (aka the predicates) has the same number of params as theQuery
    mysql_stmt_result_metadata()
    mysql_num_fields(); // to assert the output bind object has the same number of params as theQuery
    mysql_free_result(metadata);
    mysql_stmt_bind_param(); // called IF there are input params
    mysql_stmt_bind_result(); // pretty much always called for the output params
}
// and at last
mysql_stmt_execute();
//mysql_stmt_store_result();  //{OPTIONAL: use if you want to buffer the fetch - I dont}
mysql_stmt_fetch();   // ERROR! commands out of sync.

// and for completeness, 
mysql_stmt_free_result();
mysql_stmt_close();

// and the shutdown
mysql_close();
mysql_library_end();

3 个答案:

答案 0 :(得分:3)

我害怕这个...但是经过不少的工作,我得到了一个问题的答案,并解决了这个问题。 (是的,我是一个懒惰的程序员......我希望别人会告诉我这一切都是必要的......呵呵)

以下是我自己对嵌入式服务器+准备好的语句的权威答案。

问题:嵌入式支持stmts吗?答案......他们应该是,但他们不是。

是的,嵌入式mysql中有一个关于stmts的错误。看到: http://bugs.mysql.com/bug.php?id=62136

齐周先生非常尊重我。他以某种方式确定在运行嵌入时,mysql_stmt_execute()错误地将结果状态设置为“MYSQL_STATUS_GET_RESULT”而不是“MYSQL_STATUS_STATEMENT_GET_RESULT”(即将stmt视为非法则)这显然会导致“命令不同步”错误。所以它需要修补源代码本身。

怎么做.. MySql“如何在Windows上构建”页面:http://dev.mysql.com/doc/refman/5.5/en/source-installation.html

引用这个更容易阅读,如何构建: http://www.chriscalender.com/?p=689

我在此过程中确定的其他HOW-TO说明

克里斯的VS2008表达方式如何。我使用2010 Pro并学习了cmake -G arg可以省略。对我来说,2010年是自动确定使用的编译器。

我只安装了cmake和bison。这不需要perl和bazaar。我得到了标准的5.5.22源发行版而不是从集市上拉。

re:安装野牛:

  • 确保将bison安装到没有空格的路径
  • 不允许安装程序在开始菜单中添加任何内容(导致“m4.exe没有 发现“错误”
  • 手动将bison的bin文件夹添加到系统PATH

re:signtool.exe

确保将signtool的路径添加到PATH中。示例(对我而言)

  • c:\ Program Files \ Microsoft SDKs \ Windows \ v7.0A \ bin

下载MySql的源代码发布(http://dev.mysql.com/downloads/mysql/#downloads): 通用Linux(独立于架构),压缩TAR存档(mysql-5.5.22.tar.gz)

您需要编辑{D:\ your_path} \ mysql-5.5.22 \ libmysqld \ lib_sql.cc

在第340行,你会看到:

if (res)
{
    NET *net= &stmt->mysql->net;
    set_stmt_errmsg(stmt, net);
    DBUG_RETURN(1);
}
//ADD CODE HERE
DBUG_RETURN(0);

在if codeblock和DBUG_RETURN(0)之间插入以下内容:

//kgk 2012/04/11 - see http://bugs.mysql.com/bug.php?id=62136
//  Qi Zhou's modification to allow prep'd stmts to work
else if (stmt->mysql->status == MYSQL_STATUS_GET_RESULT)
{
    stmt->mysql->status= MYSQL_STATUS_STATEMENT_GET_RESULT;
}

自己构建一个新版本的libmysqld.dll,libmysqld.lib,libmysqld.pdb

问题已解决。

当你构建了dll时,不要像我一样忘记将新的DLL移动到二进制文件的运行时文件夹中,然后想知道为什么更改没有做任何事情。叹息。

仅供参考:oracle的技术人员错误报告评论标记为[20 Feb 18:34] Sveta Smirnova 是完全没有意义的。 serverARgs与任何事情无关。

答案 1 :(得分:-1)

http://dev.mysql.com/doc/refman/5.1/en/mysql-stmt-execute.html

抱歉我的英文不好,但问题是mysql_stmt_fetch打开游标,但mysql_stmt_execute只执行mysql_stmt_store_result与游标一起工作......

答案 2 :(得分:-2)

嵌入式MySQL是一个通常不使用的,对于这个问题,我已经在网上搜索了很多次,我准备了一个单独的项目。在这样做的过程中,我学到了很多东西,其中一件事就是首先执行查询然后存储结果。

要删除不同类型的查询,请创建一个执行对象并返回结果,在这种情况下,您不必一次又一次地编写执行查询。

在本例中,用户也没有执行查询并尝试存储结果,这只有在您尝试复制其他命令时才会发生。因此,问题的解决方案是执行mysql_stmt_execute,然后调用mysql_stmt_store_result