【问题标题】:Binding query param in LENGTH() condition doesn't work在 LENGTH() 条件下绑定查询参数不起作用
【发布时间】:2020-03-29 17:57:15
【问题描述】:

我在查找有关此问题的任何信息时遇到了一些麻烦,但这似乎是 SQLite 的限制。

考虑一个简单的words 表,它有两个字段,_id(整数)和word(文本)。以下查询有效并返回预期结果(所有单词不超过 12 个字符):

SELECT * FROM words WHERE LENGTH(word) <= 12;

但是,如果此字符限制需要是动态的并作为参数,则查询将不再有效。 它返回表的所有行:

String query = "SELECT * FROM words WHERE LENGTH(word) <= ?";
Cursor cursor = database.rawQuery(query, new String[]{ Integer.toString(12) });

我也尝试选择长度作为新列,然后将条件应用于该列,但结果相同:

String query = "SELECT w.*, LENGTH(w.word) AS word_length FROM words w WHERE word_length <= ?";
Cursor cursor = database.rawQuery(query, new String[]{ Integer.toString(12) });

我唯一的选择是之后只过滤查询结果吗?为什么普通 INT 列上的参数化条件可以工作,但 LENGTH() 上却不行? (例如WHERE _id &lt; ? 工作正常)

【问题讨论】:

    标签: java android sqlite android-sqlite


    【解决方案1】:

    执行的sql语句:

    rawQuery(query, new String[]{ Integer.toString(12) });
    

    是:

    SELECT * FROM words WHERE LENGTH(word) <= '12';
    

    而不是:

    SELECT * FROM words WHERE LENGTH(word) <= 12;
    

    因为rawQuery() 将所有传递的参数视为字符串,并将它们全部括在单引号内。
    所以整数 LENGTH(word) 与像 12 这样的字符串文字进行比较,这就是 SQLite 的一个特性,它指出:

    INTEGER 或 REAL 值小于任何 TEXT 或 BLOB 值。

    (来自Datatypes In SQLite Version 3)。
    所以所有整数都被认为小于字符串文字'12'

    当然,这不是您想要和期望的,所以您可以强制将 '12' 转换为整数 12,您可以通过添加 0 来实现:

    String query = "SELECT * FROM words WHERE LENGTH(word) <= ? + 0";
    

    这样做是将'12' 隐式转换为12,因为您对其应用了数值运算。

    【讨论】:

    • 谢谢,这是有道理的 - 我认为让我失望的主要原因是为什么像 _id &lt;= '12' 这样的整数字段没有这个问题。
    • 没有这个没有这个问题。 SQLite 的这一特性不适用于列值和表达式,例如 cast(length(word) as int) 或 sum(length(word)),因为它们都强制转换为整数。
    【解决方案2】:

    当然,一旦我橡皮鸭,我就可以通过将字段转换为整数来找出解决方法:

    String query = "SELECT * FROM words WHERE CAST(LENGTH(word) AS INTEGER) <= ?";
    Cursor cursor = database.rawQuery(query, new String[]{ Integer.toString(12) });
    

    似乎过多,但我猜 LENGTH() 的返回值不被视为整数(我遇到的所有文档都只是说它“返回字符数”)

    【讨论】:

      【解决方案3】:

      你试过Integer.parseInt() 吗?我认为您的查询需要整数参数,并且您正在将其转换为字符串:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多