【问题标题】:How to use a string in a Sql argument?如何在 Sql 参数中使用字符串?
【发布时间】:2020-11-22 21:27:11
【问题描述】:

应该如何在 SQL 参数中插入字符串?

类似这样的:

string clas = "Computer Science";

sql = "SELECT * from STUDENTS where CLASS='clas'";

【问题讨论】:

  • 谨防 SQL 注入。您应该使用准备好的语句

标签: c++ sql sqlite


【解决方案1】:

有两种方法:

  1. 这是首选且更安全的方式。您可以使用这样的准备好的语句
string clas = "Computer Science";
sql = "SELECT * FROM Students WHERE Class=?";

// Prepare the request right here

preparedStatement.setString(1, clas);

// Execute the request down here
  1. 一个更简单但安全性低得多的选项(它容易受到 SQL 注入的攻击)
string clas = "Computer Science";
sql = "SELECT * FROM Students WHERE Class='" + clas + "'";

【讨论】:

  • 这就是为什么我说第二个选项是首选且更安全
  • 感谢反馈,我改了顺序
  • 感谢您的回答。自动取款机我不打算做任何安全的事情。第二个答案给了我这个错误: Error (active) E0413 no proper conversion function from "std::basic_string, std::allocator>" to "char *" exists any想法?
【解决方案2】:

简单回答:

你可以这样做:

string clas = "Computer Science";
sql = "SELECT * FROM Students WHERE Class='" + clas + "'";

好答案

但是,我们可以做得更好。如果需要多值替换怎么办,那怎么办?看下面的代码,它可以替换多个字符串。此外,如果需要,您可以编写 sql 注入检查。最棒的是,您只需调用 prepare() 函数即可完成。

使用说明:

在需要放置字符串的地方使用 ?。如果需要多个字符串替换,在调用prepare函数时将所有字符串按顺序排列(作为参数)。另外,请注意准备函数调用prepare(sql, {param_1, param_2, param_3, ..., param_n})

[注意:它适用于 c++11 及更高版本。它不适用于 c++11 预版本。因此,在编译时,请使用 -std=c++11 标志和 g++]

#include <iostream>
#include <string>
#include <initializer_list>

using namespace std;


// write code for sql injection if you think
// it necessary for your program
// is_safe checks for sql injection
bool is_safe(string str) {
    // check if str is sql safe or not
    // for sql injection
    return true; // or false if not sql injection safe
}

void prepare(string &sql, initializer_list<string> list_buf) {
    int idx = 0;
    int list_size = (int)list_buf.size();
    
    int i = 0;
    for(string it: list_buf) {
        // check for sql injection
        // if you think it's necessary
        if(!is_safe(it)) {
            // throw error
            // cause, sql injection risk
        }

        if(i >= list_size) {
            // throw error
            // cause not enough params are given in list_buf
        }

        idx = sql.find("?", idx);
        if (idx == std::string::npos) {
            if(i < list_size - 1) {
                // throw error
                // cause not all params given in list_buf are used
            }
        }
        sql.replace(idx, 1, it);

        idx += 1; // cause "?" is 1 char
        i++;
    }
}

// now test it
int main() {
    string sql = "SELECT * from STUDENTS where CLASS=?";
    string clas = "clas";

    prepare(sql, {clas});

    cout << sql << endl;


    string sql2 = "select name from class where marks > ? or attendence > ?";
    string marks = "80";
    string attendence = "40";

    prepare(sql2, {marks, attendence});

    cout << sql2 << endl;

    return 0;
}

[P.S.]:如果有不清楚的地方,请随时提问。

【讨论】:

    猜你喜欢
    • 2015-03-21
    • 2021-09-24
    • 2019-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-03
    • 1970-01-01
    相关资源
    最近更新 更多