删除时找不到日期列
Date column not being found when delete
我有这个不删除任何行的语句。
DELETE FROM mytable
WHERE
datecolumn = sysdate + 100;
但是,如我所料,下面的删除了 57K 行。为什么会这样? mytable 中的日期列存储为 DATE 变量类型。
DELETE FROM mytable
WHERE
to_char(datecolumn, 'DD/MM/YYYY') = to_char(sysdate + 100, 'DD/MM/YYYY');
在 Oracle 中,date
——尽管它的名字——有一个时间组件。 sysdate
-- 尽管它的名字 -- 也有一个时间部分。
因此,第一个版本正在比较确切日期和时间,但没有匹配项。第二个是只比较日期部分。
请注意,通常不需要将日期转换为字符串。
为了提高性能,您可以将第二个写成:
where datecolumn >= trunc(sysdate) + interval '100' day and
datecolumn < trunc(sysdate) + interval '101' day;
这使得优化器更容易,因为列上没有函数。
这很可能是因为 DATECOLUMN
包含一个“截断的”日期,即没有时间部分的值(因为它被设置为 00:00:00)。
Sysdate
,另一方面,returns 完整的日期 + 时间值,因此没有匹配项并且 DELETE
不会删除任何内容。
而不是你的第二个代码(它使用 TO_CHAR
并防止使用 datecolumn
上的可能索引),稍微修改你的第一个查询:
DELETE FROM mytable
WHERE datecolumn = trunc(sysdate) + 100;
我有这个不删除任何行的语句。
DELETE FROM mytable
WHERE
datecolumn = sysdate + 100;
但是,如我所料,下面的删除了 57K 行。为什么会这样? mytable 中的日期列存储为 DATE 变量类型。
DELETE FROM mytable
WHERE
to_char(datecolumn, 'DD/MM/YYYY') = to_char(sysdate + 100, 'DD/MM/YYYY');
在 Oracle 中,date
——尽管它的名字——有一个时间组件。 sysdate
-- 尽管它的名字 -- 也有一个时间部分。
因此,第一个版本正在比较确切日期和时间,但没有匹配项。第二个是只比较日期部分。
请注意,通常不需要将日期转换为字符串。
为了提高性能,您可以将第二个写成:
where datecolumn >= trunc(sysdate) + interval '100' day and
datecolumn < trunc(sysdate) + interval '101' day;
这使得优化器更容易,因为列上没有函数。
这很可能是因为 DATECOLUMN
包含一个“截断的”日期,即没有时间部分的值(因为它被设置为 00:00:00)。
Sysdate
,另一方面,returns 完整的日期 + 时间值,因此没有匹配项并且 DELETE
不会删除任何内容。
而不是你的第二个代码(它使用 TO_CHAR
并防止使用 datecolumn
上的可能索引),稍微修改你的第一个查询:
DELETE FROM mytable
WHERE datecolumn = trunc(sysdate) + 100;