【发布时间】:2018-08-14 02:24:19
【问题描述】:
我想将(自定义)类“表”的数据插入到我的数据库中 - 数据是从内部文件中检索的,但为了安全起见,我想假设来源不受信任。目前,我正在使用以下代码的变体。这显然容易受到 SQL 注入的影响,因为 v.toString() 可能会被利用。 table.getName() 会根据表白名单进行检查,因此这里不需要防御 SQL 注入。
QString rowQuery = "INSERT INTO " + table.getName() + " VALUES ";
for (Row* r : table) {
rowQuery += "(";
for (QVariant v : r.getValues()) {
rowQuery += v.toString();
rowQuery += ","
}
rowQuery.chop(1);
rowQuery += "),";
}
rowQuery.chop(1);
QSqlQuery::exec(rowQuery)
包含两个条目和三列的示例查询如下所示:
INSERT INTO DebugTable VALUES (cell1x1, cell1x2, cell1x3), (cell2x1, cell2x2, cell2x3)
为了使我的应用程序免受 SQL 注入攻击,我开始使用预准备语句。不幸的是,这种设计选择极大地影响了性能,因此我尝试使用 QVariantLists 使用批处理执行,但即使这种方法也无法提供适当的性能。我最大的表有 15,000 个条目;如果没有准备好的语句,插入 (q.exec() / q.execBatch()) 大约需要 4 秒,而使用准备好的语句需要 90 秒。
QList<QVariantList> columnVectors;
QString queryString;
queryString = "INSERT INTO " + table.getName() + " VALUES (";
for (auto i : table.getCols()) {
columnVectors.append(QVariantList());
queryString += "?,";
}
queryString.chop(1);
queryString += ")";
for (Row* row : table.getRows()) {
for (int i = 0; i < row->getValues().length(); i++) {
columnVectors[i].append(variant);
}
}
QSqlQuery q;
q.prepare(queryString);
for (QVariantList columnVector : columnVectors) {
q.addBindValue(columnVector);
}
q.execBatch();
一个包含 x 个三列条目的示例查询如下所示:
INSERT INTO DebugTable VALUES (?, ?, ?)
我认为我的方法/实现中可能存在错误,因为我读到准备好的语句应该可以提高性能。任何帮助将不胜感激,谢谢
【问题讨论】:
-
有趣。但你能让它更简单吗?就像为这两个示例提供一个固定的查询字符串一样。 (并衡量其表现)
标签: sql qt prepared-statement sql-injection qsqlquery