在 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 don
t 知道这对您是否有用。 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 一起使用?