


Common pitfalls and best practices in Oracle database date addition and subtraction operations
Implicit conversion traps for Oracle date addition and subtraction
In Oracle database, when mathematical operations on values of type DATE or TIMESTAMP (such as adding or subtracting a number), Oracle treats it as days to add or subtract. However, if the TO_DATE function is introduced in the process, and its input parameters are implicitly converted strings, or the format model does not match the actual data, it can lead to unexpected results, especially when processing the year.
In the original question, the SQL statement is as follows:
UPDATE CUS_LOGS SET START_DATE=to_date(systimestamp 3,'DD-MON-RRRRR'), END_DATE=to_date(systimestamp 21921,'DD-MON-RRRR') WHERE CUS_ID IN ('9b90cb8175ba0ca60175ba12d8711006');
The core problem here is to_date(systimestamp N,'DD-MON-RRRR'). Although our intention is to add the number of days directly to systimestamp, the TO_DATE function forces Oracle to implicitly convert the result of systimestamp N (a TIMESTAMP type) to a string after performing addition, and then try to convert it back to the DATE type using the 'DD-MON-RRRRR' format model.
This implicit conversion process is affected by the NLS_DATE_FORMAT parameter of the current session. If NLS_DATE_FORMAT is set to DD-MON-RR or DD-MON-YY, then the year part may contain only two digits when implicitly converted to a string. For example, 2082-11-08 may be implicitly converted to '08-NOV-82'. When the TO_DATE function attempts to convert '08-NOV-82' back to date with the 'DD-MON-RRRR' format model, the RRR format model interprets the two-bit year 82 as 1982 (because the RR format usually interprets 00-49 as 20xx, 50-99 as 19xx, and RRRR will use this explanation in this context), rather than the expected 2082, resulting in a year error.
The following example demonstrates the effect of NLS_DATE_FORMAT on implicit conversion: Assume the current date is 2022-11-02.
-- Set the date format of the session to DD-MON-RR, simulate the environment that may cause problems ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-RR'; SELECT TO_DATE(SYSDATE 3,'DD-MON-RRRR') AS "A (2022 3 days)", TO_CHAR(TO_DATE(SYSDATE 3,'DD-MON-RRRR'), 'YYYY-MM-DD') AS "B (YYYY format of A)," TO_DATE(SYSDATE 21921,'DD-MON-RRRR') AS "C (2022 21921 days)", TO_CHAR(TO_DATE(SYSDATE 21921,'DD-MON-RRRR'), 'YYYY-MM-DD') AS "D (YYYY format of C)", TO_DATE(SYSDATE 3,'DD-MON-YYYY') AS "E (2022 3 days, YYYY)", TO_CHAR(TO_DATE(SYSDATE 3,'DD-MON-YYYY'), 'YYYY-MM-DD') AS "F (YYYY format of E)", TO_DATE(SYSDATE 21921,'DD-MON-YYYY') AS "G (2022 21921 Days, YYYY)", TO_CHAR(TO_DATE(SYSDATE 21921,'DD-MON-YYYY'), 'YYYY-MM-DD') AS "H (YYYY format of G)" FROM DUAL;
Execute the above query and you will observe results similar to the following (the specific date depends on the execution date):
A (2022 3 days) | B (YYYY format of A) | C (2022 21921 days) | D (YYYY format of C) | E (2022 3 days, YYYY) | F (YYYY format of E) | G (2022 21921 days, YYYY) | H (YYYY format of G) |
---|---|---|---|---|---|---|---|
05-NOV-22 | 2022-11-05 | 08-NOV-82 | 1982-11-08 | 05-NOV-22 | 0022-11-05 | 08-NOV-82 | 0082-11-08 |
From the results, we can see that when the calculation result is 2082-11-08, 82 is misunderstood as 1982 because it is implicitly converted to the two-bit year string '08-NOV-82' and then parsed by TO_DATE(..., 'DD-MON-RRRRR'). If DD-MON-YYYY is used, the two-digit year 82 will be interpreted as 0082, which is even more deviant.
Correct date addition and subtraction operation
Oracle database itself supports adding and subtracting numbers to adjust dates directly by adding and subtracting numbers to DATE and TIMESTAMP types. A number represents a day. Therefore, to increase the date or timestamp to a specified number of days, the most direct and safe way is to avoid any unnecessary TO_DATE or TO_CHAR conversions.
Use SYSTIMESTAMP or SYSDATE to add or subtract the number of days directly
SYSTIMESTAMP returns the current system date and time (including time zone), and SYSDATE returns the current system date and time (excluding time zone, accuracy to seconds). Both can be added and subtracted directly with numbers.
-- Example: Directly add and subtract SYSTIMESTAMP-- It is recommended to set NLS_TIMESTAMP_TZ_FORMAT first to display the TIMESTAMP result clearly ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD HH24:MI:SS TZR'; ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'; SELECT SYSTIMESTAMP AS "current timestamp", SYSTIMESTAMP 3 AS "Timestamp after 3 days", SYSTIMESTAMP 21921 AS "21921 Days Time Stamp" FROM DUAL;
The results will clearly show the correct future date:
Current timestamp | Time stamp after 3 days | Time stamp after 21921 days |
---|---|---|
2022-11-02 10:42:24 00:00 | 2022-11-05 10:42:24 00:00 | 2082-11-08 10:42:24 00:00 |
If only the date part is needed, or the target column is of DATE type, it is more concise to use SYSDATE:
-- Example: Directly add and subtract SELECT to SYSDATE SYSDATE AS "Current Date", SYSDATE 3 AS "Date after 3 days", SYSDATE 21921 AS "Date after 21921 Days" FROM DUAL;
The result is also correct:
Current date | 3 days later date | 21921 days later date |
---|---|---|
2022-11-02 | 2022-11-05 | 2082-11-08 |
Remove the time part: Use TRUNC()
If you want the date part of the calculation to start from midnight of the day (00:00:00) the time part can be truncated using the TRUNC() function. TRUNC (sysdate) will set the time part of sysdate to midnight.
-- Example: Use TRUNC() to ensure that SELECT is calculated from midnight of the day TRUNC(SYSDATE) AS "Midnight of the day", TRUNC(SYSDATE) 3 AS "Midnight in 3 days", TRUNC(SYSDATE) 21921 AS "21921 Days After Midnight" FROM DUAL;
This is useful for ensuring date consistency, for example, when you only care about dates and not about specific points in time.
Final solution
According to the above analysis, the original UPDATE statement should be modified to perform date arithmetic directly, and the option to use TRUNC() to ensure that the time part starts from midnight.
UPDATE CUS_LOGS SET START_DATE = TRUNC(SYSDATE) 3, END_DATE = TRUNC(SYSDATE) 21921 WHERE CUS_ID IN ('9b90cb8175ba0ca60175ba12d8711006');
This SQL statement avoids any TO_DATE call that may cause implicit conversion problems, and directly utilizes Oracle's built-in support for adding and subtracting numbers of date types, ensuring the accuracy of the calculation.
Further date operation considerations
Although direct addition and subtraction of numbers are suitable for days, Oracle provides special functions for adding and subtracting months or years:
- ADD_MONTHS(date, integer) : Used to increase or decrease a month on a specified date. For example, ADD_MONTHS(TRUNC(SYSDATE), 60*12) can increase the date by 60 years. It should be noted that ADD_MONTHS will handle the end of the month date, for example, adding one month to January 31 will get February 28 (or 29).
- INTERVAL Literal : Time intervals can be more explicitly represented, such as SYSDATE INTERVAL '3' DAY or SYSTIMESTAMP INTERVAL '1' YEAR. However, the INTERVAL YEAR TO MONTH type may cause an error when handling February 29 spanning a leap year, for example, DATE '2020-02-29' INTERVAL '1' YEAR throws an invalid date error because there is no February 29 in 2021. For adding and subtracting days, adding numbers directly is usually easier and safer.
When choosing a date operation method, the most direct and implicit conversions should be given priority. For adding or subtracting days, it is best practice to add or subtract numbers directly to values of DATE or TIMESTAMP types.
Summarize
When doing date addition and subtraction operations in Oracle databases, be sure to be alert to the pitfalls that implicit type conversion and NLS_DATE_FORMAT parameters may bring, especially when it comes to TO_DATE functions and two-bit year format models (such as RR). Best practices are:
- Avoid unnecessary TO_DATE or TO_CHAR conversions : When you need to increase or decrease the number of days on the values of DATE or TIMESTAMP types, just add or subtract them directly.
- Use TRUNC() function : If you need to reset the time part of the date to midnight (00:00:00), use TRUNC(date).
- Understanding the impact of NLS parameters : Understand how the NLS_DATE_FORMAT settings of a session affect implicit string conversion of date and timestamps, which helps diagnose potential problems.
- Select the appropriate function : For date operations other than days (such as months or years), use special functions such as ADD_MONTHS and pay attention to their behavioral characteristics.
Following these principles can ensure that your Oracle date operations are accurate and avoid business problems caused by date calculation errors.
The above is the detailed content of Common pitfalls and best practices in Oracle database date addition and subtraction operations. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

HashMap implements key-value pair storage through hash tables in Java, and its core lies in quickly positioning data locations. 1. First use the hashCode() method of the key to generate a hash value and convert it into an array index through bit operations; 2. Different objects may generate the same hash value, resulting in conflicts. At this time, the node is mounted in the form of a linked list. After JDK8, the linked list is too long (default length 8) and it will be converted to a red and black tree to improve efficiency; 3. When using a custom class as a key, the equals() and hashCode() methods must be rewritten; 4. HashMap dynamically expands capacity. When the number of elements exceeds the capacity and multiplies by the load factor (default 0.75), expand and rehash; 5. HashMap is not thread-safe, and Concu should be used in multithreaded

Virtual threads have significant performance advantages in highly concurrency and IO-intensive scenarios, but attention should be paid to the test methods and applicable scenarios. 1. Correct tests should simulate real business, especially IO blocking scenarios, and use tools such as JMH or Gatling to compare platform threads; 2. The throughput gap is obvious, and it can be several times to ten times higher than 100,000 concurrent requests, because it is lighter and efficient in scheduling; 3. During the test, it is necessary to avoid blindly pursuing high concurrency numbers, adapting to non-blocking IO models, and paying attention to monitoring indicators such as latency and GC; 4. In actual applications, it is suitable for web backend, asynchronous task processing and a large number of concurrent IO scenarios, while CPU-intensive tasks are still suitable for platform threads or ForkJoinPool.

TosetJAVA_HOMEonWindows,firstlocatetheJDKinstallationpath(e.g.,C:\ProgramFiles\Java\jdk-17),thencreateasystemenvironmentvariablenamedJAVA_HOMEwiththatpath.Next,updatethePATHvariablebyadding%JAVA\_HOME%\bin,andverifythesetupusingjava-versionandjavac-v

ServiceMesh is an inevitable choice for the evolution of Java microservice architecture, and its core lies in decoupling network logic and business code. 1. ServiceMesh handles load balancing, fuse, monitoring and other functions through Sidecar agents to focus on business; 2. Istio Envoy is suitable for medium and large projects, and Linkerd is lighter and suitable for small-scale trials; 3. Java microservices should close Feign, Ribbon and other components and hand them over to Istiod for discovery and communication; 4. Ensure automatic injection of Sidecar during deployment, pay attention to traffic rules configuration, protocol compatibility, and log tracking system construction, and adopt incremental migration and pre-control monitoring planning.

To correctly handle JDBC transactions, you must first turn off the automatic commit mode, then perform multiple operations, and finally commit or rollback according to the results; 1. Call conn.setAutoCommit(false) to start the transaction; 2. Execute multiple SQL operations, such as INSERT and UPDATE; 3. Call conn.commit() if all operations are successful, and call conn.rollback() if an exception occurs to ensure data consistency; at the same time, try-with-resources should be used to manage resources, properly handle exceptions and close connections to avoid connection leakage; in addition, it is recommended to use connection pools and set save points to achieve partial rollback, and keep transactions as short as possible to improve performance.

The key to implementing a linked list is to define node classes and implement basic operations. ①First create the Node class, including data and references to the next node; ② Then create the LinkedList class, implementing the insertion, deletion and printing functions; ③ Append method is used to add nodes at the tail; ④ printList method is used to output the content of the linked list; ⑤ deleteWithValue method is used to delete nodes with specified values and handle different situations of the head node and the intermediate node.

Create and use SimpleDateFormat requires passing in format strings, such as newSimpleDateFormat("yyyy-MM-ddHH:mm:ss"); 2. Pay attention to case sensitivity and avoid misuse of mixed single-letter formats and YYYY and DD; 3. SimpleDateFormat is not thread-safe. In a multi-thread environment, you should create a new instance or use ThreadLocal every time; 4. When parsing a string using the parse method, you need to catch ParseException, and note that the result does not contain time zone information; 5. It is recommended to use DateTimeFormatter and Lo

To improve the performance of Java collection framework, we can optimize from the following four points: 1. Choose the appropriate type according to the scenario, such as frequent random access to ArrayList, quick search to HashSet, and concurrentHashMap for concurrent environments; 2. Set capacity and load factors reasonably during initialization to reduce capacity expansion overhead, but avoid memory waste; 3. Use immutable sets (such as List.of()) to improve security and performance, suitable for constant or read-only data; 4. Prevent memory leaks, and use weak references or professional cache libraries to manage long-term survival sets. These details significantly affect program stability and efficiency.
