Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Bằng (=) so với LIKE cho kiểu dữ liệu ngày tháng

Giả sử LAST_TRANSACTION_DATEDATE cột (hoặc TIMESTAMP ) thì cả hai phiên bản đều rất tệ.

Trong cả hai trường hợp, DATE cột sẽ được chuyển đổi hoàn toàn thành một ký tự chữ dựa trên cài đặt NLS hiện tại. Điều đó có nghĩa là với những khách hàng khác nhau, bạn sẽ nhận được những kết quả khác nhau.

Khi sử dụng các ký tự ngày luôn luôn sử dụng to_date() với (!) một mặt nạ định dạng hoặc sử dụng một ký tự ngày ANSI. Bằng cách đó, bạn so sánh ngày với ngày không phải chuỗi với chuỗi. Vì vậy, để so sánh bình đẳng, bạn nên sử dụng:

LAST_TRANSACTION_DATE = to_date('30-JUL-07', 'dd-mon-yy')

Lưu ý rằng việc sử dụng 'MON' vẫn có thể dẫn đến lỗi với các cài đặt NLS khác nhau ('DEC' so với 'DEZ' hoặc 'MAR' so với 'MRZ' ). Việc sử dụng số tháng (và năm có bốn chữ số) sẽ ít bị lỗi hơn nhiều:

LAST_TRANSACTION_DATE = to_date('30-07-2007', 'dd-mm-yyyy')

hoặc sử dụng ký tự ngày ANSI

LAST_TRANSACTION_DATE = DATE '2007-07-30'

Bây giờ, lý do tại sao truy vấn trên rất có thể không trả về gì là trong Oracle DATE các cột cũng bao gồm cả thời gian. Các ký tự ngày ở trên ẩn chứa thời gian 00:00 . Nếu thời gian trong bảng khác (ví dụ:19:54 ) thì tất nhiên ngày tháng không bằng nhau.

Để giải quyết vấn đề này, bạn có các tùy chọn khác nhau:

  1. sử dụng trunc() trên cột của bảng để "chuẩn hóa" thời gian thành 00:00 trunc(LAST_TRANSACTION_DATE) = DATE '2007-07-30 Tuy nhiên, điều này sẽ ngăn việc sử dụng chỉ mục được xác định vào LAST_TRANSACTION_DATE
  2. sử dụng between
    LAST_TRANSACTION_DATE between to_date('2007-07-30 00:00:00', 'yyyy-mm-dd hh24:mi:ss') and to_date('2007-07-30 23:59:59', 'yyyy-mm-dd hh24:mi:ss')

Sự cố hiệu suất của giải pháp đầu tiên có thể được khắc phục bằng cách tạo chỉ mục vào trunc(LAST_TRANSACTION_DATE) có thể được sử dụng bởi biểu thức đó. Nhưng biểu thức LAST_TRANSACTION_DATE = '30-JUL-07' cũng ngăn chặn việc sử dụng chỉ mục vì nó được xử lý nội bộ dưới dạng to_char(LAST_TRANSACTION_DATE) = '30-JUL-07'

Những điều quan trọng cần nhớ:

  1. Đừng bao giờ dựa vào chuyển đổi kiểu dữ liệu ngầm định. Nó sẽ cung cấp cho bạn vấn đề tại một số điểm. Luôn so sánh các loại dữ liệu chính xác
  2. Oracle DATE cột luôn chứa thời gian là một phần của quy tắc so sánh.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kết nối C # với Oracle

  2. Nhóm các bản ghi từng giờ hoặc từng ngày và lấp đầy khoảng trống bằng 0 hoặc rỗng

  3. Cách thay đổi ngôn ngữ cho phiên Oracle của bạn

  4. Câu lệnh FORALL với Mệnh đề ràng buộc INDICES-OF trong Cơ sở dữ liệu Oracle

  5. Nhóm theo các giá trị theo thứ tự