Không bao giờ, đừng bao giờ sử dụng TO_DATE()
vào thứ gì đó đã là DATE
. Lý do cho điều này là vì Oracle sẽ phải thực hiện một số chuyển đổi ngầm để làm theo mong muốn của bạn:
TO_DATE(sysdate, 'mm-yyyy')
thực sự được chạy dưới dạng
TO_DATE(TO_CHAR(sysdate, '<default nls_date_format parameter>'), 'mm-yyyy')
vì vậy nếu nls_date_format của bạn được đặt thành thứ gì đó không phải là 'mm-yyyy', bạn sẽ gặp sự cố. Thông số nls_date_format mặc định là 'DD-MON-YY', nhiều khả năng là giá trị của bạn được đặt thành.
Nếu tất cả những gì bạn muốn làm là add_months vào ngày 1 của tháng hiện tại, thì bạn nên sử dụng TRUNC()
, ví dụ:
add_months(trunc(sysdate, 'MM'),-12)
Đây là bằng chứng về to_char ngầm nếu bạn cập nhật điều gì đó đã là một ngày, theo yêu cầu của Lalit - một kế hoạch thực thi của một truy vấn cơ bản liên quan đến to_date (sysdate):
SQL_ID 3vs3gzyx2gtcn, child number 0
-------------------------------------
select * from dual where to_date(sysdate) < sysdate
Plan hash value: 3752461848
----------------------------------------------------------------------------
| Id | Operation | Name | E-Rows |E-Bytes| Cost (%CPU)| E-Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 2 (100)| |
|* 1 | FILTER | | | | | |
| 2 | TABLE ACCESS FULL| DUAL | 1 | 2 | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(TO_DATE(TO_CHAR([email protected]!))<[email protected]!)
Bạn có thể thấy rõ ràng TO_CHAR()
trong điều kiện bộ lọc.