【发布时间】:2017-11-26 21:32:25
【问题描述】:
我有一个简单的表,我必须将日期信息存储在 DATE 和 VARCHAR2 列中:
CREATE TABLE date_test(date_in_varchar VARCHAR2(30), date_in_date DATE);
INSERT INTO date_test values ('06/21/2017 01:30:00 AM', to_date('06/21/2017 01:01:03 AM', 'MM/DD/YYYY HH:MI:SS AM'));
INSERT INTO date_test values ('06/22/2017 02:45:00 AM', to_date('06/22/2017 05:06:01 AM', 'MM/DD/YYYY HH:MI:SS AM'));
INSERT INTO date_test values ('06/23/2017 05:51:20 AM', to_date('06/23/2017 12:00:05 AM', 'MM/DD/YYYY HH:MI:SS AM'));
如您所见,数据格式为“MM/DD/YYYY HH:MI:SS AM”。我必须准备比较以变量 l_attr_val 格式传递的日期 'MM/DD/YYYY' 和存储在表中的日期。现在我的问题是:为过滤器编写查询最好和最安全的方法是什么:equals、like、greater、lower,可以肯定的是,我不会面临隐式转换?我假设,对于存储为日期的值和存储为 varchar 的值,该查询会有所不同。
CASE 1:日期存储在DATE 列中,它有关于day, month, year, hour, minutes, seconds. 的信息我还有一个变量(VARCHAR2 类型),它只有day, month, year 的信息。 (l_attr_val = '06/21/2017')。现在我想在这个变量和存储在表中的值之间创建一个相等过滤器,仅基于日期,没有时间(我得到 2017 年 6 月 21 日的变量,我想查看 2017 年 6 月 21 日的所有记录,无论时间)。
SELECT * FROM date_test WHERE date_in_date = TO_DATE('06/22/2017', 'MM/DD/YYYY');
由于时代原因,它给了我 0 行。
案例 2,与案例 1 不同:
案例 1:日期存储在 VARCHAR2 列中,它有关于 day, month, year, hour, minutes, seconds. 的信息我还有一个变量(VARCHAR2 类型),它的信息只有 day, month, year。 (l_attr_val = '06/21/2017')。现在我想在这个变量和存储在表中的值之间创建一个相等过滤器,仅基于日期,没有时间(我得到 2017 年 6 月 21 日的变量,我想查看 2017 年 6 月 21 日的所有记录,无论时间)。
SELECT * FROM date_test WHERE TO_DATE(date_in_varchar, 'MM/DD/YYYY HH:MI:SS AM' = TO_DATE('06/22/2017', 'MM/DD/YYYY');
那么,在上述情况下比较日期最安全的方法是什么?
【问题讨论】:
-
为什么要处理这个问题?只需使用
date将日期存储在数据库中。当你返回值时,你可以使用to_char()来设置你喜欢的格式。 -
为什么必须将日期存储为字符串?只需将实际日期存储为正确的数据类型,并根据需要让客户端格式化为字符串。并且只使用实际日期进行过滤,就像您的 PL/SQL 块正在做的那样。 (如果真的有必要,您可以添加一个虚拟列 (11g+),将日期格式化为字符串,或在表格顶部添加一个视图,但仍不过滤该字符串值)。
-
@GordonLinoff 不幸的是,在我正在处理的项目中,某些日期存储在 varchar 列中,我必须处理它。是的,如果所有日期都存储在 DATE 列中会简单得多。这就是我问这个问题的原因。
-
I think it would work properly for date stored in date (if I am wrong please tell me why)- 如果 date_in_date 列中的所有日期都设置为午夜,您的查询将起作用;如果你可以在那里有实际时间,你需要检查一个范围,例如date_in_date >= TO_DATE(l_attr_val, 'MM/DD/YYYY') and date_in_date < TO_DATE(l_attr_val, 'MM/DD/YYYY') + 1 -
如果 date 和 varchar 不匹配,你会使用哪个?我认为您需要编辑您的问题以解释您真正在做什么以及您需要更清楚地执行哪些规则。
标签: sql oracle date datetime plsql