如何摆脱SQL查询的字符串连接

时间:2016-02-07 11:34:39

标签: c++ mysql database qt qt5

我刚刚编写了以下代码:

QSqlQuery query(_db);
QString sql =
    "SELECT company_name, server_name, product_name, product_version, license_end, last_update, comment"
    " FROM foo WHERE";
if (!include_unlimited)
{
    sql += " license_end > NOW() AND license_end != '9999-01-01'";
}
else if (!include_trial)
{
    sql += " license_end = '9999-01-01'";
}
else
{
    sql += " license_end > NOW()";
}
if (product_name != "*")
{
    sql += " AND product_name = :product_name";
}
sql += " ORDER BY license_end";
query.prepare(
    sql
);
if (sql.contains(":product_name"))
{
    query.bindValue(":product_name", product_name);
}
query.exec();
while (query.next())
{
    LicenseInfo license;
    license.company_name = query.value(0).toString();
    license.server_name = query.value(1).toString();
    license.product_name = query.value(2).toString();
    license.product_version = query.value(3).toInt();
    license.license_end = query.value(4).toString();
    license.last_update = query.value(5).toString();
    license.comment = query.value(6).toString();
    licenses.append(license);
}

如何摆脱SQL查询的字符串连接?

1 个答案:

答案 0 :(得分:1)

如果您不想连接,只需编写整个查询,包含所有前提条件并使用绑定变量启用,禁用where子句。像这样:

var statement: COpaquePointer = nil
if sqlite3_prepare_v2(sqliteDB, "PRAGMA foreign_keys", -1, &statement, nil) != SQLITE_OK {
    let err = String.fromCString(sqlite3_errmsg(sqliteDB))
    print("error building statement: \(err)")
}
if sqlite3_step(statement) != SQLITE_ROW {
    print("expected a row")
}
let foreignKeysEnabled = sqlite3_column_int(statement, 0) != 0
sqlite3_finalize(statement)
print("enabled: \(foreignKeysEnabled)")

我没有在MySQL上测试它,但是在一些必须在单个select语句中实现大量逻辑的情况下使用了这种方法。

然后,绑定部分可能会像:

SELECT company_name, server_name, product_name
     , product_version, license_end, last_update, comment
  FROM foo
 WHERE (   (:include_unlimited IS NOT NULL AND license_end > NOW() AND license_end != '9999-01-01') 
        OR (:include_trial IS NOT NULL AND license_end = '9999-01-01')
        OR (:include_trial IS NULL AND :include_unlimited IS NULL AND license_end > NOW())
       )
   AND (product_name = :product_name OR :product_name = '*')
 ORDER BY product_name