【发布时间】:2020-06-29 08:04:49
【问题描述】:
我对 Oracle 中的 CASE 有疑问。 例如,我有一个包含两列的表,并希望根据这两列创建第三列。
第一列包含天和月的组合,存储为 NUMBER,例如2305 --> 5 月 23 日、503 --> 3 月 5 日等。这些值都是有效日期或 NULL。第二列有年份(存储为 NUMBER,NOT NULL),例如2019 年,2018 年。 我现在想从这两个列中创建一个 DATE 列,这样如果第一列中的值为 NULL,那么新列应该为 NULL,否则第一列和第二列的串联作为 DATE . 例如
day year result
2305 2018 --> 23/05/2018
505 2019 --> 05/05/2019
NULL 2020 --> NULL
我试过了:
CASE WHEN day IS NOT NULL THEN TO_DATE (LPAD (TO_CHAR (day || year), 8, '0'), 'dd/mm/yyyy') ELSE NULL END AS date
但它会抛出错误“ORA-01847 day of month must be between 1 and last day of month”。
我在 Stack Overflow 上搜索并发现有时,在检查 WHEN 条件之前评估 CASE 语句中的“THEN”表达式。这可能是问题所在,因为当 day 为 NULL 时,LPAD 给出的结果不能转换为 DATE。有没有办法绕过这个?理想情况下,我想要一些命令告诉 Oracle 首先检查 day 是否为 NULL,然后仅在不为 NULL 时评估结果。还是有其他方法可以解决我的问题?
最好的问候。
【问题讨论】:
-
您发布的代码得到 ORA-00907。如果您只是在
year之后添加),那么它就可以工作(尽管to_char()是多余的)。该错误表明您正在进行隐式转换,但如果不查看实际代码,则很难准确判断位置。 -
@AlexPoole 仔细查看使用的格式掩码,然后与输入
TO_DATE的实际文本数据进行比较。实际上,我的回答也可能是省略了以某种方式格式化日期的步骤。 -
@Tim - Oracle doesn't error on that by default - 这通常更像是诅咒而不是祝福......即使使用 FX 也是错误的错误。
-
@AlexPoole:对不起,我忘记了(在这个问题中)一年后的“)”。但是使用“)”它对我不起作用。我现在编辑了。
-
@user13832956 - 但这有效in db<>fiddle。因此,您的代码仍然不同,或者您有其他无效数据 - 例如少于 3 位数的一天。