在 C++ MFC 程序中使用 mysql 查询中的变量

Posted

技术标签:

【中文标题】在 C++ MFC 程序中使用 mysql 查询中的变量【英文标题】:Using a variable in a mysql query, in a C++ MFC program 【发布时间】:2010-04-25 19:53:18 【问题描述】:

在网上大量搜索之后,我仍然没有找到任何解决这个问题的方法。

我正在编写一个小型 C++ 应用程序,它连接到在线数据库并在列表框中输出数据。

我需要使用编辑框启用搜索功能,但使用变量时无法使查询工作。

我的代码是:

res = mysql_perform_query (conn, "select distinct artist from Artists");
//res = mysql_perform_query (conn, "select album from Artists where artist = ' ' ");



while((row = mysql_fetch_row(res)) != NULL)
    CString str;
    UpdateData();

    str = ("%s\n", row[0]);

    UpdateData(FALSE);
    m_list_control.AddString(str);


第一行“res =”运行良好,但我需要第二行运行。我为编辑框设置了一个成员变量m_search_edit,但是我尝试将它包含在 sql 语句中的任何方式都会导致错误。

例如。

res = mysql_perform_query (conn, "select album from Artists where artist = '"+m_search_edit+" ' ");

导致此错误:

错误 C2664:“mysql_perform_query”:无法将参数 2 从“class CString”转换为“char *” 没有可以执行此转换的用户定义转换运算符,或者无法调用该运算符”

当我将 m_search_edit 转换为 char* 时,它会给我一个“无法添加 2 个指针”错误。

有没有办法解决这个问题?

【问题讨论】:

你不是在str = ...; 行中缺少sprintf 吗? 顺便说一句,您正在为 SQL 注入进行设置。对于桌面应用程序来说可能不是什么大问题,但您仍然应该正确编码m_search_edit 不,sprintf 没有工作,当我删除它时,程序工作了。对不起,我应该更清楚这是一个 MFC APP。 关于SQL注入问题,这只是一个大学的小项目,所以我现在不太担心这方面,只是想让程序先运行。不过感谢您的帮助,如果没有它,我不会知道 SQL 注入是什么。 【参考方案1】:

这里的问题是您可能正在为 Unicode 构建,这意味着 CString 由宽字符组成。您不能直接将 ASCII 字符串与宽字符串连接(也不能使用 + 运算符连接字符串文字)。

我认为在这里构建查询字符串最清晰的方法是使用CT2CA 宏将编辑控件的内容从Unicode 转换为ASCII 并CStringA::Format 将它们插入到字符串中

CStringA query;
query.Format("select album from Artists where artist = '%s'", CT2CA(m_search_edit));
res = mysql_perform_query(conn, query);

正如 Thomas 所指出的,您应该意识到这为 SQL 注入打开了大门……

编辑:我不确定这个mysql_perform_query API 来自哪里,但从您发布的错误消息来看,它似乎还需要一个可写缓冲区(char * 而不是const char *)。由于我找不到它的文档,我不知道它期望缓冲区有多大,但要从 CString 中获取可修改的缓冲区,请查看 GetBuffer() 和 ReleaseBuffer() 方法:

CStringA query;
query.Format(...); // Replace ... with parameters from above
char * buffer = query.GetBuffer(MAX_STRING_LENGTH); // make length big enough for mysql
res = mysql_perform_query(conn, buffer)
query.ReleaseBuffer();

EDIT2(回应最新评论):

感谢您提供mysql_perform_query 函数的定义。以后提出问题时,请记住,了解您何时创建了类似这样的辅助函数会很有帮助。

在这种情况下,您的mysql_perform_query 函数永远不会修改查询字符串——它唯一要做的就是将它传递给mysql_query,它接受const char *,因此您没有理由不声明它的参数const 也是。一旦你这样做了,你会发现我的第一个答案有效(不需要 GetBuffer/ReleaseBuffer):

MYSQL_RES *mysql_perform_query(MYSQL *conn, const char * query)

   // Body as written in comment.

【讨论】:

这也不起作用。如果我删除“A”,它会在“Cstring”之后留下 5 个错误,并在“A”中留下 2 个错误。这两个错误是 CT2CA: Undeclared Identifier 和 'mysql_perform_query' : cannot convert parameter 2 from 'class CString' to 'char *' 我应该在第一篇文章中指出我在 VC++ 6 上执行此操作。 我尝试在 Visual Studio 2008 中重建程序。我从您的代码中得到了这个错误:错误 1 ​​错误 C2664: 'mysql_perform_query' : cannot convert parameter 2 from 'CStringA' to 'char *' @D.Gaughan 这是什么 mysql API?我在网上找不到mysql_perform_query 的文档,只有mysql_query。无论如何,CString 只有隐式转换为const char *。如果您需要为采用非const 的函数获取可修改缓冲区,则应查看 GetBuffer() 和 ReleaseBuffer()。我正在编辑我的答案。 m using the mysql C++ connector. I have this block of code at the start of the program, I dont 知道这对您是否有用。 MYSQL_RES* mysql_perform_query(MYSQL *conn, char *sql_query) // 将查询发送到数据库 if (mysql_query(conn, sql_query)) // printf("MySQL query error : %s\n", mysql_error(conn) ); // 退出(1); 返回 mysql_use_result(conn);您发布的代码仍然给出错误。主要是那个query.Buffer(...): no重载函数包含0个参数。 @D.Gaughan 你说query.Buffer(...) 给出了错误,但这并没有出现在我的帖子中。确保你得到全名,*Get*Buffer*Release*Buffer,或者如果你正在调用 query.Format,你用第一个示例中的参数替换 ...(我只是从第二个示例中删除它们将重点放在 GetBuffer 和 ReleaseBuffer 的使用上)。

以上是关于在 C++ MFC 程序中使用 mysql 查询中的变量的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 语言中将谷歌地图 API 与 MFC 或 QT 一起使用?

如何使用 C++ 代码运行 MFC 应用程序 exe 文件?

C++ - 将 Hunspell 与 MFC 一起使用

在文档/视图 MFC c++ 中没有视图的文档

在 MFC C++ 中打开对话框

MFC C++ 应用程序:如何在任务管理器中清除命令行参数?