【发布时间】:2020-11-22 21:27:11
【问题描述】:
应该如何在 SQL 参数中插入字符串?
类似这样的:
string clas = "Computer Science";
sql = "SELECT * from STUDENTS where CLASS='clas'";
【问题讨论】:
-
谨防 SQL 注入。您应该使用准备好的语句。
应该如何在 SQL 参数中插入字符串?
类似这样的:
string clas = "Computer Science";
sql = "SELECT * from STUDENTS where CLASS='clas'";
【问题讨论】:
有两种方法:
string clas = "Computer Science";
sql = "SELECT * FROM Students WHERE Class=?";
// Prepare the request right here
preparedStatement.setString(1, clas);
// Execute the request down here
string clas = "Computer Science";
sql = "SELECT * FROM Students WHERE Class='" + clas + "'";
【讨论】:
简单回答:
你可以这样做:
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.]:如果有不清楚的地方,请随时提问。
【讨论】: