用于比较字符串和非字符串的 ANSI sql

Dav*_*542 3 sql types type-conversion database-agnostic language-lawyer

假设我有以下任一表达式:

SELECT
    DATE '2014-01-01' < '2014-02-01',
    DATE '2014-01-01' < '321',
    9 < '10',
    9 < 'a'
Run Code Online (Sandbox Code Playgroud)

SQL 标准中是否有关于如何比较这些的建议或要求?我想这三个级别或“严格性”如下:

  1. 引发错误 [最严格] —— 上面所有 4 个表达式都会失败。
  2. 尝试将字符串转换为非字符串类型,如果它不起作用,则会引发错误 - 上面的表达式 2 和 4 将失败。
  3. 尝试将字符串强制转换为非字符串类型,如果无法将非字符串强制转换为字符串,则上述所有 4 项均有效。
  4. 将非字符串操作数转换为字符串——以上 4 项均有效。

似乎BigQuery使用第二种方法,postgres使用类似2/3的东西(只有最后一个失败),mysql使用3或4(没有失败)。

标准在这里有什么建议吗?

Sal*_*n A 5

\n

标准在这里有什么建议吗?

\n
\n

我相信您是在问是否有关于自动类型转换进行比较的官方规则?答案是不*。

\n

对于比较操作,规范提到数据类型应该是可比较的。没有描述不同数据类型的比较,但它确实说隐式类型转换可以发生在表达式 [...] 中。因此RDBMS允许转换一个或两个操作数的数据类型来比较它们。

\n

话虽这么说,自动类型转换的规则取决于实现。不同 RDBMS 的规则差异很大。请查阅 RDBMS 文档以了解它们。

\n

例如,SQL Server 使用数据类型优先级将其中一个操作数的数据类型转换为与另一个操作数匹配:

\n
    \n
  • 对于DATE \'2014-01-01\' < \'2014-02-01\',将转换为 varchar 值date进行比较
  • \n
  • 对于9 < \'10\',将转换为 varchar 值int进行比较
  • \n
\n

MySQL 有一套不同的规则

\n
    \n
  • 对于DATE \'2014-01-01\' < \'2014-02-01\',两个值都将转换为时间戳(不是时间戳数据类型)以进行比较
  • \n
  • 对于9 < \'10\',两个值都将转换为浮点数进行比较
  • \n
\n

不幸的是,隐式转换有太多陷阱,应该避免。例如2.0 = \'2.01\',在 SQL Server 中是这样,2 = \'2foo\'在 MySQL 中也是这样。

\n

在字符串上使用CAST正确类型 ( DECLARE @userdate AS DATE = \'20120201\') 的函数、变量或适当的函数 ( )。STR_TO_DATE(\'01-02-2012\',\'%d-%m-%Y\')

\n
\n

* 答案基于 SQL-92 标准 \xe2\x80\x94 ,非常古老,但仍然与问题相关。

\n

  • 就像我说的,它取决于实现。*一般规则*是将具有较小范围的数据类型转换为较大范围的数据类型,以避免_意外行为_例如 2 = 2.4 返回 true。因此,至少在 SQL Server 中,date 将提升为 datetime,且 h:m:s 设置为 0。Int 将提升为 float。具有不同小数位数和精度的两个小数...两者都将转换为具有相同的精度和小数位数(两者中较大者)。再说一遍,SQL Server...您无法比较两个“文本”数据类型,因为规范没有定义确切的规则。 (2认同)