首页 > 解决方案 > C++ 和 sql SELECT 语句

问题描述

我有一个快速的问题。在尝试将 sql 和 c++ 结合在一起方面,我是新手。我的问题是当我输入作者在数据库中查找时,它说未知列“在此处插入作者姓氏”。这是因为输入变量 'AuthorLast' 在 select 语句中没有引号。问题是,我不知道如何修复或更改它。

#include<mysql.h>
#include<string>
#include<iostream>
using namespace std;
int main()
{
    string AuthorLast;
    mysql_library_init(0, NULL, NULL);
    MYSQL* con = mysql_init(NULL);
    if (con == NULL)
    {
        cout << mysql_error(con);
        exit(1);
    }
    if (mysql_real_connect(con, "Insert Host here", "Insert ID here", "Password", "DataBase here", 0, NULL, 0) == NULL)
    {
        cout << mysql_error(con);
        exit(1);
    }
    cout << "Enter in an author from the database: ";
    getline(cin, AuthorLast);
    string sql;
    sql = "SELECT AuthorLast FROM Author WHERE AuthorLast= " + AuthorLast + ";";
    const char* C = sql.c_str();
    mysql_query(con, C);
    MYSQL_RES* result = mysql_store_result(con);
    if (result == NULL)
    {
        cout << mysql_error(con);
        exit(1);
    }
    int field_nums = mysql_num_fields(result);
    MYSQL_ROW row;
    while (row = mysql_fetch_row(result))
    {
        for (int i = 0; i < field_nums; i++)
            cout << row[i] << endl;
    }
    mysql_free_result(result);
    mysql_close(con);
}

标签: c++mysqlsql

解决方案


正如其他人所说,只需在 SQL 文本中添加单引号就可以了,但这会使您容易受到 SQL 注入的攻击。假设有人要求提供作者姓名(为了清楚起见,写在另一行):

SomeAuthor' or ''='

这将导致:

SELECT AuthorLast FROM Author WHERE AuthorLast= 'SomeAuthor' or ''='';

这将导致您的查询返回所有作者的姓氏。尽管这对您来说似乎无关紧要,但如果(例如)您在密码检查查询中使用相同的方法,它可能导致攻击者能够在不知道用户密码的情况下登录(实质上,您允许用户修改您的查询)。

在将其包含在查询中之前,您应该彻底清理用户的输入(即确保它不包含意外字符)或(最好还是)使用准备好的语句(对于 mysql,我认为您可以查看mysql_stmt_*方法) .

Prepared statements 或多或少类似于告诉数据库服务器执行,"SELECT AuthorLast FROM Author WHERE AuthorLast=?"并告诉它使用"MyAuthorLast". ?因此,如果有人试图在名称中包含引号,服务器会通过添加任何必需的转义字符来自动为您清理输入。


推荐阅读