【问题标题】:Problem with handling the result of SELECT query in MYSQL C API在 MYSQL C API 中处理 SELECT 查询结果的问题
【发布时间】:2019-03-18 18:22:11
【问题描述】:

我的一个脚本出现内部服务器错误。我正在使用 MYSQL C API。 https://dev.mysql.com/doc/refman/5.6/en/c-api.html

这是我脚本的相应部分:

MYSQL *con;
MYSQL_RES *result;
MYSQL_ROW robe;

con = mysql_init(NULL);
if (!mysql_real_connect(valid values)) {
printf("Content-type: text/html\n\n");
printf("Could not connect\n");
exit(0); }

char somequery[512];
//userinput is sanitized beforehand
int sog = sprintf(somequery, "SELECT password from testtab WHERE username='%s'", userinput);

if (sog < 0) {
printf("Content-type: text/html\n\n");
printf("Something went wrong with Sprintf\n");
exit(0); }

int bos = mysql_real_query(con, somequery, strlen(somequery));
if (bos != 0) {
printf("Content-type: text/html\n\n");
printf("The query produced no result\n");
exit(0); }

result = mysql_store_result(con);
if (result == NULL) {
printf("Content-type: text/html\n\n");
printf("No Result Set Produced\n");
exit(0); }

robe = mysql_fetch_row(result);
char *passdb = robe[0];
printf("Content-type: text/html\n\n");
printf("And it is: %s", passdb);

一个 HTML 表单通过 POST 提交到这个脚本(上面可以看到其中的一部分)。当我事先提交数据库中存在的用户名时,我没有收到任何错误。一切正常。

当我提交的用户名在所述表(testtab)中不存在时,问题就出现了。好吧,我收到 500 内部服务器错误。我也查看了 Apache 错误日志:“头文件前的脚本输出结束”。

到目前为止,我已经尝试了一些方法,但都没有奏效。任何帮助表示赞赏。

注意:做 mysql_num_fields(result);在这两种情况下都给出 1。

【问题讨论】:

  • 您没有显示整个程序或整个输出集,但我敢打赌,除了您在此处显示的内容之外,还有一些东西会在查询成功时执行,而在查询时不会执行失败。因此,我担心在每次失败时使用exit(0)
  • 基本上,您需要一个类似于 finalize 步骤的东西,它总是会执行,即使出现故障也是如此。诚然只是一个猜测,我从不将 Web 服务器连接到数据库。

标签: mysql c mariadb mysql-connector-c


【解决方案1】:

首先,您不应该将密码存储在数据库中,尤其是可以通过在线服务访问的数据库。 exit(0) 表示成功。它还在完成之前使您的输出短路。您不能只在产生输出的过程中调用 exit(0)。改用某种“数据不可用”字符串。

【讨论】:

  • 1.如果不在数据库中,您建议将密码存储在哪里(尽管这一点与我面临的问题无关) 2. 您在说哪个“退出(0)”?他们都没有在中间剪掉剧本。请记住,只有当我输入错误的用户名(数据库中不存在的用户名)时我才会遇到问题。
  • 您的数据库是否为不存在的用户生成密码?查询失败时退出。存储用户密码的加密哈希。
  • 1.兄弟,你没有回答我的问题。如果不在数据库中(处于加密状态),您还建议在哪里存储密码?目前我这样做。 2.我不知道你的意思是“为不存在的用户生成密码”。我有一个示例数据库,其中包含一些示例数据(手动插入)。与唯一用户名对应的密码。 3.我完全不知道你所说的“查询失败时退出”是什么意思。请根据需要改写。
  • 我确实回答了你的问题。永远不要这样做。而是存储密码的加密哈希。
  • 没关系。我整晚都和家人在一起,无法专注于此。
【解决方案2】:

感谢一些好人的帮助,我在其他地方找到了解决方案。看来,我犯了一个愚蠢的错误,并且需要彻底了解两个 MYSQL C API 函数之间的区别。

我在这里写下答案,希望它可以使其他人受益。

错误就在这里:

 robe = mysql_fetch_row(result);

虽然它本身是正确的。我没有检查它的结果。发生的情况是,当使用事先在数据库中不存在的用户名执行 SQL 查询时,结果是一个空集(而不是错误)。

这里 mysql_store_result 和 mysql_fetch_row 略有不同。如果集合为空,前者不会返回 NULL,而后者会。

我所要做的就是在上面的逻辑行之后添加一个检查:

if (robe == NULL) { 
//error occured 
} else { //go on 
}

【讨论】:

    猜你喜欢
    • 2023-03-20
    • 2020-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多