Oracle SQL Developer 获取早于 n 个月的表行
在 Oracle SQL Developer 中,我有一个名为 t1 的表,其中有两列 col1 定义为 NUMBER(19,0),col2 定义为 TIMESTAMP(3)。 我有这些行
col1 col2
1 03/01/22 12:00:00,000000000
2 03/01/22 13:00:00,000000000
3 26/11/21 10:27:11,750000000
4 26/11/21 10:27:59,606000000
5 16/12/21 11:47:04,105000000
6 16/12/21 12:29:27,101000000
我的 sysdate 看起来像这样:
select sysdate from dual;
SYSDATE
03/03/22
我想创建一个存储过程(SP),它将删除超过 2 个月的行并显示消息 n 行已删除
但是当我执行此语句时,
select * from t1 where to_date(TRUNC(col2), 'DD/MM/YY') < add_months(sysdate, -2);
我没有得到前 2 行我的 t1 表。我得到超过 2 行
1 03/01/22 12:00:00,000000000
2 03/01/22 13:00:00,000000000
我怎样才能得到这些行并删除它?
In Oracle SQL Developer, I have a table called t1 who have two columns col1 defined as NUMBER(19,0) and col2 defined as TIMESTAMP(3).
I have these rows
col1 col2
1 03/01/22 12:00:00,000000000
2 03/01/22 13:00:00,000000000
3 26/11/21 10:27:11,750000000
4 26/11/21 10:27:59,606000000
5 16/12/21 11:47:04,105000000
6 16/12/21 12:29:27,101000000
My sysdate looks like this:
select sysdate from dual;
SYSDATE
03/03/22
I want to create a stored procedure (SP) which will delete rows older than 2 months and displayed message n rows are deleted
But when i execute this statement
select * from t1 where to_date(TRUNC(col2), 'DD/MM/YY') < add_months(sysdate, -2);
I don't get the first 2 rows of my t1 table. I get more than 2 rows
1 03/01/22 12:00:00,000000000
2 03/01/22 13:00:00,000000000
How can i get these rows and deleted it please ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 Oracle 中,
DATE
数据类型是由 7 个字节(世纪、世纪年份、月、日、小时、分钟和秒)组成的二进制数据类型。它始终具有所有这些组件,并且从不以特定格式(例如DD/MM/RR
)存储。您的客户端应用程序(即 SQL Developer)可以选择将二进制
DATE
值格式化为DD/MM/RRDISPLAY > 但这是您正在使用的客户端应用程序的功能,而不是数据库的功能。
当您显示整个值时:
然后它输出(取决于时区):
如果您将其与您的值进行比较,您会发现
2022-01-03 12:00:00
不是“超过 2 个月前”,因此它不会被匹配。您似乎想要的不是“超过 2 个月前”,而是“等于或超过 2 个月,忽略时间部分,前”;您可以使用:
或
(注意:第一个查询将使用
col2
上的索引,但第二个查询不会;它需要TRUNC( col2)
而不是。)另外,不要在已经是
DATE
或TIMESTAMP
的列上使用TO_DATE
> 数据类型。TO_DATE
采用字符串作为第一个参数,而不是DATE
或TIMESTAMP
,因此 Oracle 将使用TO_CHAR
执行隐式转换> 如果格式模型不匹配,那么您将引入错误(并且由于任何用户都可以随时在其会话参数中设置自己的日期格式,因此您可能会遇到一个用户的错误,而其他用户则不会出现这些错误,并且非常严重)很难调试)。db<>fiddle 此处
In Oracle, a
DATE
data type is a binary data type consisting of 7 bytes (century, year-of-century, month, day, hour, minute and second). It ALWAYS has all of those components and it is NEVER stored with a particular formatting (such asDD/MM/RR
).Your client application (i.e. SQL Developer) may choose to DISPLAY the binary
DATE
value in a human readable manner by formatting it asDD/MM/RR
but that is a function of the client application you are using and not the database.When you show the entire value:
Then it outputs (depending on time zone):
If you compare that to your values then you can see that
2022-01-03 12:00:00
is not "more than 2 months ago" so it will not be matched.What you appear to want is not "more than 2 months ago" but "equal to or more than 2 months, ignoring the time component, ago"; which you can get using:
or
(Note: the first query would use an index on
col2
but the second query would not; it would require a function-based index onTRUNC(col2)
instead.)Also, don't use
TO_DATE
on a column that is already aDATE
orTIMESTAMP
data type.TO_DATE
takes a string as the first argument and not aDATE
orTIMESTAMP
so Oracle will perform an implicit conversion usingTO_CHAR
and if the format models do not match then you will introduce errors (and since any user can set their own date format in their session parameters at any time then you may get errors for one user that are not present for other users and is very hard to debug).db<>fiddle here
也许只是:
Perhaps just: