为了账号安全,请及时绑定邮箱和手机立即绑定

in子句和占位符

in子句和占位符

qq_遁去的一_1 2019-07-06 17:33:27
in子句和占位符我试图在Android中执行以下SQL查询:    String names = "'name1', 'name2";   // in the code this is dynamically generated     String query = "SELECT * FROM table WHERE name IN (?)";     Cursor cursor = mDb.rawQuery(query, new String[]{names});然而,Android并没有用正确的值代替问号。但是,我可以这样做,但这并不能防止SQL注入:    String query = "SELECT * FROM table WHERE name IN (" + names + ")";     Cursor cursor = mDb.rawQuery(query, null);我如何才能绕过这个问题,并能够使用IN子句?
查看完整描述

3 回答

?
慕的地6264312

TA贡献1817条经验 获得超6个赞

如公认答案中所示,但不使用自定义函数生成逗号分隔的“?”。请检查下面的代码。

String[] names = { "name1", "name2" }; // do whatever is needed first
String query = "SELECT * FROM table"
    + " WHERE name IN (" + TextUtils.join(",", Collections.nCopies(names.length, "?"))  + ")";Cursor cursor = mDb.rawQuery(query, names);


查看完整回答
反对 回复 2019-07-06
?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

表单的字符串"?, ?, ..., ?"可以是动态创建的字符串,并安全地放入原始SQL查询(因为它是不包含外部数据的受限表单),然后占位符可以正常使用。

考虑一个函数String makePlaceholders(int len)返回len用逗号分隔的问号,然后:

String[] names = { "name1", "name2" }; // do whatever is needed firstString query = "SELECT * FROM table"
    + " WHERE name IN (" + makePlaceholders(names.length) + ")";Cursor cursor = mDb.rawQuery(query, names);

只要确保传递的值和地方一样多就行了。默认最大值主机参数极限在SQLite中是999-至少在正常的构建中,不确定Android:)

编码愉快。


以下是一个实现:

String makePlaceholders(int len) {
    if (len < 1) {
        // It will lead to an invalid query anyway ..
        throw new RuntimeException("No placeholders");
    } else {
        StringBuilder sb = new StringBuilder(len * 2 - 1);
        sb.append("?");
        for (int i = 1; i < len; i++) {
            sb.append(",?");
        }
        return sb.toString();
    }}


查看完整回答
反对 回复 2019-07-06
  • 3 回答
  • 0 关注
  • 906 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信