Giả sử LAST_TRANSACTION_DATE
là một DATE
cột (hoặc TIMESTAMP
) sau đó cả hai phiên bản là thực hành rất xấu.
Trong cả hai trường hợp, cột DATE
sẽ được chuyển hoàn toàn thành ký tự theo chữ dựa trên cài đặt NLS hiện tại.Điều đó có nghĩa với các khách hàng khác nhau, bạn sẽ nhận được kết quả khác nhau.
Khi sử dụng ngày literals luôn sử dụng to_date()
với (!) Một mặt nạ dạng hoặc sử dụng một ngày ANSI chữ. Bằng cách đó bạn so sánh ngày tháng với ngày không phải là chuỗi với chuỗi. Vì vậy, cho sự so sánh tương đươ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 sai sót với các thiết lập khác nhau NLS ('DEC'
vs 'DEZ'
hoặc 'MAR'
vs 'MRZ'
). Đó là ít hơn nhiều lỗi dễ sử dụng số tháng (và bốn năm chữ số):
LAST_TRANSACTION_DATE = to_date('30-07-2007', 'dd-mm-yyyy')
hoặc sử dụng một ngày ANSI đen
LAST_TRANSACTION_DATE = DATE '2007-07-30'
Bây giờ lý do tại sao các truy vấn trên là rất có khả năng trở lại không có gì là rằng trong các cột Oracle DATE
cũng bao gồm thời gian. Các chữ ngày tháng ẩ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 các ngày không bằng nhau.
Để workaround vấn đề này, bạn có các tùy chọn khác nhau:
- sử dụng
trunc()
trên cột bảng để "bình thường hóa" thời gian để 00:00
trunc(LAST_TRANSACTION_DATE) = DATE '2007-07-30
này tuy nhiên sẽ ngăn chặn việc sử dụng một chỉ số xác định trên LAST_TRANSACTION_DATE
- 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')
Vấn đề hiệu suất của giải pháp đầu tiên có thể được giải quyết bằng cách tạo chỉ mục trên trunc(LAST_TRANSACTION_DATE)
có thể được sử dụng bởi biểu thức đó. Nhưng khái niệm LAST_TRANSACTION_DATE = '30-JUL-07'
ngăn chặn một cách sử dụng chỉ số cũng vì nội nó được xử lý như to_char(LAST_TRANSACTION_DATE) = '30-JUL-07'
Những điều quan trọng cần nhớ:
- Không bao giờ, bao giờ dựa vào chuyển đổi kiểu dữ liệu ngầm. Nó sẽ cung cấp cho bạn các 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
- Oracle
DATE
các cột luôn chứa thời gian là một phần của quy tắc so sánh.
Nguồn
2013-08-29 08:23:27
Tôi đoán cột đầu tiên chỉ khớp với '30-Jul-07 00: 00: 00' trong khi cột thứ hai khớp với' 30-Jul-07 **: **: ** '? –