我们的应用程序有时必须动态创建 SQL 查询,包括ORDER BY
类似这样的子句:
ORDER BY CASE t.ID
WHEN 895 THEN 1
WHEN 643 THEN 2
END
问题t.ID
通常出在NUMBER
列上 — — 但很少出在VARCHAR
列上(取决于表,提醒您,表是动态的)。
当发生这种情况时,我们会收到如下错误(下面是本地化版本,但很容易弄清楚):
SQL 错误 [932] [42000]: ORA-00932: несовместимые типы данных: ожидается CHAR, получено NUMBER
尽管我们的 RDBMS 可以执行隐式类型转换,但显然它无法工作WHEN
(出于某种原因)。我在文档中没有找到任何关于它的提及(欢迎您提供这样的参考)。
以下是复现脚本(该示例确实有些牵强):
create table "user"(
id VARCHAR(50),
name VARCHAR(50)
);
insert into "user"
values ('1', 'John Doe'),
('2', 'John Roe'),
('3', 'Jane Doe');
select * from "user"
order by case id
when 1 then 1
when 2 then 2
end;
用这个替换最后一个脚本以使其工作
select * from "user"
order by case id
when '1' then 1
when '2' then 2
end;
您的建议是什么?
Oracle DB、Postgres(我们两者都使用)。
¹除了“永远不要依赖隐式类型转换”
我的建议是始终转换为字符串:
那么它应该适用于数字和字符串,因为所有数字都可以转换为字符串。
根据您的需要调整长度。
注意。如果您确定
id
永远不会为空,COALESCE
则可以删除这是 Oracle 数据库不进行隐式转换的少数情况之一。 摘自文档:
请注意,尽管字符串“1”可以转换为数字,但这两种方法都会失败:
为了解决这个问题,您可以转换表达式。在 Oracle 数据库中,搜索的案例表达式将进行隐式转换: