SQLite Affinity Bug?

时间:2018-04-15 17:24:12

标签: sqlite

编辑: 答案在这里:Is floating point math broken?有助于理解这个问题。但是,这个问题与语言无关。它特定于由SQLite处理的浮点数的记录行为和亲和性。对不同的问题有一个非常相似的答案!=重复的问题。

问题: 我有一个相当复杂的SQLite Where子句比较数值。我已阅读并且"思考"我在这里了解数据类型文档:https://www.sqlite.org/datatype3.html

仍然对SQLite用于确定比较子句中的数据类型的逻辑感到困惑,例如=,>,<,<>我可以将我的例子缩小到这一点测试SQL,结果对我来说没什么意义。

reconnectFailed

select语句(TestComparison2)中的第二个表达式是将等式的左侧转换为TEXT值。我可以通过将等式的右侧转换为TEXT并且结果= 1来证明这一点。

显然,我错过了SQLite计算Affinity的方式。这些值来自大型/复杂查询中的列。我应该将WHERE / Join子句中的等式的两边都投射到TEXT以避免这些问题吗?

1 个答案:

答案 0 :(得分:1)

您未获得预期结果的原因是基础结果将是浮点数。

虽然DataTypes in SQLite3涵盖的很多,但您还应该考虑 Expressions 中的以下部分: -

  

类型名转换处理的亲和力

     

NONE

     

将值转换为没有亲和力的类型名称会导致该值转换为BLOB。投射到BLOB包括第一个   在数据库连接的编码中将值转换为TEXT,   然后将得到的字节序列解释为BLOB而不是   TEXT。

     

TEXT

     

要将BLOB值转换为TEXT,组成BLOB的字节序列将被解释为使用数据库编码的文本   编码

     

将一个INTEGER或REAL值转换为TEXT会将该值渲染为via   sqlite3_snprintf()除了生成的TEXT使用的编码   数据库连接。

     

REAL

     

将BLOB值转换为REAL时,该值首先转换为TEXT。

     

将TEXT值转换为REAL时,最长可能的前缀   可以解释为实数的值是从中提取的   TEXT值和余数被忽略。 TEXT中的任何前导空格   从TEXT收敛到REAL时忽略值。

     

如果没有可以解释为实数的前缀,则   转换结果为0.0。

     

INTEGER

     

将BLOB值转换为INTEGER时,该值首先转换为TEXT。   将TEXT值转换为INTEGER时,可以解释为可以解释为整数的值> gt的最长前缀   从TEXT值和余数忽略。任何领先的空间   从TEXT转换为INTEGER时的TEXT值将被忽略。

     

如果没有可以解释为整数的前缀,   转换结果为0.

     

如果前缀整数大于+9223372036854775807那么   演员阵容的结果正好是+9223372036854775807。   同样,如果   前缀整数小于-9223372036854775808然后得到的结果   演员阵容正好是-9223372036854775808。

     

当转换为INTEGER时,如果文本看起来像带有指数的浮点值,则指数将被忽略,因为它不是   整数前缀的一部分。例如,“(CAST'123e + 5'AS INTEGER)”   结果是123,而不是12300000。

     

CAST运算符仅理解十进制整数 - 十六进制整数的转换停止在“0x”前缀的“x”处   十六进制整数字符串,因此CAST的结果始终为零。

     

将REAL值转换为INTEGER会导致REAL值与零之间的整数最接近REAL值。如果   REAL大于最大可能的有符号整数   (+9223372036854775807)然后结果是最大可能的签名   整数,如果REAL小于最小可能的有符号整数   (-9223372036854775808)然后结果是最不可能的签名   整数。

     

在SQLite版本3.8.2(2013-12-06)之前,将大于+9223372036854775807.0的REAL值转换为整数会导致   最负的整数,-9223372036854775808。这种行为意味着   在执行等效操作时模拟x86 / x64硬件的行为   铸造。

     

NUMERIC

     

首先将TEXT或BLOB值转换为NUMERIC强制转换为REAL,然后将结果进一步转换为   INTEGER当且仅当从REAL转换为INTEGER无损时   并且可逆。 这是SQLite中唯一的NUMERIC上下文   和INTEGER的亲密关系表现不同

     

将REAL或INTEGER值转换为NUMERIC是一种无操作,即使是真实的   value可以无损地转换为整数。

在此部分之前有一个关于文字值的部分(即,可能只需要将投射应用于从列中提取的值)。

尝试: -

SELECT
    round(CAST(10 AS NUMERIC) + CAST(254.53 AS NUMERIC),2) = round(CAST(264.53 AS NUMERIC),2) AS TestComparison1,

    round(CAST(10 AS NUMERIC) + CAST(254.54 AS NUMERIC),2) = round(CAST(264.54 AS NUMERIC),2) AS TestComparison2

: - enter image description here