我试图确定用于将数字与相同数字的字符或字符串版本进行比较的标准 SQL 行为。(或类似的)是否SELECT 1 = '1'
总是返回某种“真实”值(true
、1
、't'
等)?我已经在 PostgreSQL 和 MySQL 上确认了很多,但我找不到整个 SQL 的资源。
更新:问题的目的是我试图弄清楚在选择/插入/更新/等时是否使用不带引号的数字。来自其值为数字的非数字字段。
我试图确定用于将数字与相同数字的字符或字符串版本进行比较的标准 SQL 行为。(或类似的)是否SELECT 1 = '1'
总是返回某种“真实”值(true
、1
、't'
等)?我已经在 PostgreSQL 和 MySQL 上确认了很多,但我找不到整个 SQL 的资源。
更新:问题的目的是我试图弄清楚在选择/插入/更新/等时是否使用不带引号的数字。来自其值为数字的非数字字段。
SELECT 1='1'
Give TRUE
since是我已知的所有实现中'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> }... ]
因为<quote>
仅包含在<bit string literal>
, <hex string literal>
, ... 中,但不包含在数字文字中...
“SQL
一般”没有“真实”价值的概念。
与MySQL
and不同PostgreSQL
,在Oracle
and中SQL Server
,内部数据类型不能用作WHERE
子句或WHEN
谓词中的布尔值。
您应该始终在这些子句中使用某种谓词。
不能使用任何数据类型mydata
来使这些查询起作用:
SELECT 1
WHERE @mydata
或者
SELECT 1
FROM dual
WHERE :mydata
此外,没有SQL
标准规定类型转换顺序。
常量的数据类型可以转换为列数据类型的数据类型,反之亦然。
这可能会导致与此问题中描述的问题类似的问题。
SQL 服务器
if 1 = '1'
print 'yes'
else
print 'no'
输出:是
这将被转换,请参阅此处以获取完整的隐式和显式转换可能性列表:CAST 和 CONVERT (Transact-SQL)
首先,在 SQL ServerSELECT 1 = '1'
中无效。虽然,如果你运行下面的代码,你会发现 1 does = '1'
if (1 = '1') begin
print 'true'
end else begin
print 'false'
end
结果:
true
1 是一个数字,'1' 是某种 CHAR 数组,它们永远不应该相等。如果是,那是依赖于实现的行为
从 MySQL 5.x 和 SQL Server 2005 进行测试,它们都执行'1'
into的隐式转换,1
以便评估返回 true。
但这也可能与整理有关。
从更新:
您的更新听起来像您想要执行以下操作:
SELECT *
FROM MyTable
WHERE StringColumn = 1
那不管用。如果您在该字符串列中有任何非数字值,则一旦 sql 引擎到达该行,它将引发错误。在 MS SQL Server 中,错误是“将 varchar 值 'blah' 转换为数据类型 int 时转换失败。 ”
因此,如果要进行比较,则必须确保您正在比较类似的数据类型。例如:
SELECT *
FROM MyTable
WHERE StringColumn = '1'
尽管它似乎在许多实现中都有效,但根据 SQL 标准,1 = '1'
不允许进行比较。
问题(鉴于更新文本)不是:
SELECT 1 = '1'
会工作,但会:
SELECT '1'::text = 1
工作。这当然是:不。至少在 PostgreSQL 上,这是有充分理由的。
对于“始终为真”的选择语句,只需使用SELECT 1
. 这将永远是真的。