在SQL中,1始终等于'1'吗?

3
我正在尝试确定将数字与其字符或字符串版本进行比较的标准SQL行为。 SELECT 1 = '1'(或类似语句)是否总是返回某种“真实”值(true1't'等)?我已在PostgreSQL和MySQL上确认了这一点,但我找不到关于整个SQL的资源。
更新:问题的目的是我想弄清楚在从值为数字的非数字字段选择/插入/更新等操作中,是否可以使用没有引号的数字。

1
甚至在SQL Server 2005中似乎都无法解析。 - Joey
继续投票:MySQL 5.1; SELECT 1 = '1' -> 1 - Boldewyn
考虑到您的更新,答案是肯定的。 - Johannes Weiss
10个回答

6

SELECT 1='1' 的结果为TRUE,因为在我所知道的所有实现中,'1' 是正确的INT构造器。

但是SQL使用严格类型检查,可以看到:

# SELECT 1=CAST('1' AS TEXT);
ERROR:  operator does not exist: integer = text
LINE 1: SELECT 1=CAST('1' AS TEXT);
                ^
HINT:  No operator matches the given name and argument type(s). You might need to add  explicit type casts.

关于标准(SQL 92、99和2003),似乎存在错误:

     <literal> ::=
            <signed numeric literal>
          | <general literal>

     <general literal> ::=
            <character string literal>
          | <national character string literal>
          | <bit string literal>
          | <hex string literal>
          | <datetime literal>
          | <interval literal>

     <signed numeric literal> ::=
          [ <sign> ] <unsigned numeric literal>

     <unsigned numeric literal> ::=
            <exact numeric literal>
          | <approximate numeric literal>

     <exact numeric literal> ::=
            <unsigned integer> [ <period> [ <unsigned integer> ] ]
          | <period> <unsigned integer>

     <unsigned integer> ::= <digit>...

     <character string literal> ::=
          [ <introducer><character set specification> ]
          <quote> [ <character representation>... ] <quote>
            [ { <separator>... <quote> [ <character representation>... ] <quote> }... ]

由于<引用>仅包含在<位串字面量><十六进制串字面量>等中,而不包含在数字字面量中...


2

首先,在SQL Server中,SELECT 1 = '1'是无效的。尽管如此,如果您运行以下代码,您会发现1确实等于'1'

if (1 = '1') begin
    print 'true'
end else begin
    print 'false'
end

结果:

true

2
"SQL in general"没有“truthy”值的概念。
MySQLPostgreSQL不同,在OracleSQL Server中,内部数据类型不能用作WHERE子句或WHEN谓词中的布尔值。
您应该始终使用某种谓词来在这些子句中使用。
没有任何数据类型可以在mydata中用于使这些查询起作用:
SELECT  1
WHERE   @mydata

或者

SELECT  1
FROM    dual
WHERE   :mydata

此外,没有任何SQL标准规定类型转换的顺序。

常量的数据类型可以转换为列数据类型或反之亦然。

这可能会导致类似于此问题中描述的问题。


1
SQL自1999年以来就有布尔类型。 - Peter Eisentraut
SQL通常确实有“真”和“假”的概念 - 这被称为布尔值,并且自1999年以来一直是SQL标准的一部分。而MySQL没有真正的布尔类型。它愚蠢地接受任何可以转换为不等于“0”的数字的东西作为“真”。任何无法转换为数字或为“0”的内容都被视为“假”。 - user330315

2

SQL Server

if 1 = '1'
print 'yes'
else
print 'no'

输出:是

这将被转换,可以在此处查看整个隐式和显式转换的列表:CAST和CONVERT(Transact-SQL)


1

1是一个数字,而'1'是某种类型的字符数组,它们永远不应该相等。如果它们相等,那就是实现相关的行为。


1
请记住,当必要或方便时,SQL会进行很多类型转换。它并不完全像Java。 - Joey
这并不意味着它是正确的,你永远不应该有意地这样做。 显式比隐式更好。 - user177800
选择1作为a 联合全部 选择'1' - SQLMenace

1

从MySQL 5.x和SQL Server 2005测试来看,它们都会将'1'隐式转换为1,以便进行评估并返回true。

但这也可能与排序规则有关。


0

根据更新的文本,问题并不在于:

SELECT 1 = '1'

会工作,但会:

SELECT '1'::text = 1

工作。当然是不行的,至少在PostgreSQL上是这样的,而且有很好的理由。


在至少8.2.11版本中,第二个查询返回“t”。 - Daniel Vandersluis

0

来自更新:

根据您的更新,您想要做以下事情:

SELECT *
FROM MyTable 
WHERE StringColumn = 1

那样做是行不通的。如果该字符串列中有任何非数字值,当SQL引擎到达该行时,它将抛出一个错误。在MS SQL Server中,错误信息为“Conversion failed when converting the varchar value 'blah' to data type int.

因此,如果您想进行比较,您必须确保比较的数据类型相同。例如:

SELECT *
FROM MyTable 
WHERE StringColumn = '1'

0

尽管在许多实现中似乎可以工作,但根据SQL标准,比较1 = '1'是不允许的。


-1

如果需要一个“始终为真”的选择语句,只需使用SELECT 1。这将始终为真。


我知道,这个问题的目的是确定查询中的 ... WHERE non_numeric_field = 1 是否等同于 ... WHERE non_numeric_field = '1' - Daniel Vandersluis
1
那不正确。在SQL中,1和true不是相同的东西。或许在某些实现中会有所不同。 - Peter Eisentraut

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接