SELECT 1 = '1'
(或类似语句)是否总是返回某种“真实”值(true
,1
,'t'
等)?我已在PostgreSQL和MySQL上确认了这一点,但我找不到关于整个SQL的资源。更新:问题的目的是我想弄清楚在从值为数字的非数字字段选择/插入/更新等操作中,是否可以使用没有引号的数字。
SELECT 1 = '1'
(或类似语句)是否总是返回某种“真实”值(true
,1
,'t'
等)?我已在PostgreSQL和MySQL上确认了这一点,但我找不到关于整个SQL的资源。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> }... ]
由于<引用>
仅包含在<位串字面量>
、<十六进制串字面量>
等中,而不包含在数字字面量中...
首先,在SQL Server中,SELECT 1 = '1'
是无效的。尽管如此,如果您运行以下代码,您会发现1确实等于'1'
if (1 = '1') begin
print 'true'
end else begin
print 'false'
end
结果:
true
SQL
in general"没有“truthy”值的概念。MySQL
和PostgreSQL
不同,在Oracle
和SQL Server
中,内部数据类型不能用作WHERE
子句或WHEN
谓词中的布尔值。mydata
中用于使这些查询起作用:SELECT 1
WHERE @mydata
或者
SELECT 1
FROM dual
WHERE :mydata
此外,没有任何SQL
标准规定类型转换的顺序。
常量的数据类型可以转换为列数据类型或反之亦然。
这可能会导致类似于此问题中描述的问题。
SQL Server
if 1 = '1'
print 'yes'
else
print 'no'
输出:是
这将被转换,可以在此处查看整个隐式和显式转换的列表:CAST和CONVERT(Transact-SQL)
1是一个数字,而'1'是某种类型的字符数组,它们永远不应该相等。如果它们相等,那就是实现相关的行为。
从MySQL 5.x和SQL Server 2005测试来看,它们都会将'1'
隐式转换为1
,以便进行评估并返回true。
但这也可能与排序规则有关。
根据更新的文本,问题并不在于:
SELECT 1 = '1'
会工作,但会:
SELECT '1'::text = 1
工作。当然是不行的,至少在PostgreSQL上是这样的,而且有很好的理由。
来自更新:
根据您的更新,您想要做以下事情:
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'
尽管在许多实现中似乎可以工作,但根据SQL标准,比较1 = '1'
是不允许的。
如果需要一个“始终为真”的选择语句,只需使用SELECT 1
。这将始终为真。
... WHERE non_numeric_field = 1
是否等同于 ... WHERE non_numeric_field = '1'
。 - Daniel Vandersluis
SELECT 1 = '1'
-> 1 - Boldewyn