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

Trừ ngày trong Oracle - Kiểu dữ liệu số hoặc khoảng thời gian?

Được rồi, tôi thường không tự trả lời các câu hỏi của mình nhưng sau một hồi mày mò, tôi đã tìm ra cách Oracle lưu trữ kết quả của một phép trừ DATE.

Khi bạn trừ đi 2 ngày, giá trị không phải là kiểu dữ liệu NUMBER (như bạn tin trong sổ tay Tham khảo SQL 11.2 Oracle). Số kiểu dữ liệu nội bộ của một phép trừ DATE là 14, là kiểu dữ liệu nội bộ không được lập thành văn bản (NUMBER là kiểu dữ liệu nội bộ số 2). Tuy nhiên, nó thực sự được lưu trữ dưới dạng 2 số có dấu bổ sung riêng biệt, với 4 byte đầu tiên được sử dụng để biểu thị số ngày và 4 byte cuối cùng được sử dụng để biểu thị số giây.

Ví dụ về phép trừ DATE dẫn đến chênh lệch số nguyên dương:

select date '2009-08-07' - date '2008-08-08' from dual;

Kết quả trong:

DATE'2009-08-07'-DATE'2008-08-08'
---------------------------------
                              364

select dump(date '2009-08-07' - date '2008-08-08') from dual;

DUMP(DATE'2009-08-07'-DATE'2008
-------------------------------
Typ=14 Len=8: 108,1,0,0,0,0,0,0

Nhớ lại rằng kết quả được biểu diễn dưới dạng phần bù 2 tách biệt của hai có dấu 4 byte. Vì không có số thập phân trong trường hợp này (chính xác là 364 ngày và 0 giờ), 4 byte cuối cùng đều là số 0 và có thể bị bỏ qua. Đối với 4 byte đầu tiên, vì CPU của tôi có kiến ​​trúc nhỏ, các byte được đảo ngược và phải được đọc là 1.108 hoặc 0x16c, là số thập phân 364.

Ví dụ về phép trừ DATE dẫn đến chênh lệch số nguyên âm:

select date '1000-08-07' - date '2008-08-08' from dual;

Kết quả trong:

DATE'1000-08-07'-DATE'2008-08-08'
---------------------------------
                          -368160

select dump(date '1000-08-07' - date '2008-08-08') from dual;

DUMP(DATE'1000-08-07'-DATE'2008-08-0
------------------------------------
Typ=14 Len=8: 224,97,250,255,0,0,0,0

Một lần nữa, vì tôi đang sử dụng một máy endian nhỏ, các byte được đảo ngược và phải được đọc là 255,250,97,224 tương ứng với 11111111 11111010 01100001 11011111. Bây giờ vì đây là mã hóa số nhị phân có dấu bổ sung của hai byte, chúng tôi biết rằng số là âm vì chữ số nhị phân ngoài cùng bên trái là số 1. Để chuyển số này thành số thập phân, chúng ta sẽ phải đảo ngược phần bù của 2 (trừ 1 rồi thực hiện phần bù của một người), kết quả là:00000000 00000101 10011110 00100000 bằng -368160 như nghi ngờ.

Ví dụ về phép trừ DATE dẫn đến chênh lệch số thập phân:

select to_date('08/AUG/2004 14:00:00', 'DD/MON/YYYY HH24:MI:SS'
 - to_date('08/AUG/2004 8:00:00', 'DD/MON/YYYY HH24:MI:SS') from dual;

TO_DATE('08/AUG/200414:00:00','DD/MON/YYYYHH24:MI:SS')-TO_DATE('08/AUG/20048:00:
--------------------------------------------------------------------------------
                                                                             .25

Chênh lệch giữa 2 ngày đó là 0,25 ngày hoặc 6 giờ.

select dump(to_date('08/AUG/2004 14:00:00', 'DD/MON/YYYY HH24:MI:SS')
 - to_date('08/AUG/2004 8:00:00', 'DD/MON/YYYY HH24:MI:SS')) from dual;

DUMP(TO_DATE('08/AUG/200414:00:
-------------------------------
Typ=14 Len=8: 0,0,0,0,96,84,0,0

Bây giờ lần này, vì sự khác biệt là 0 ngày và 6 giờ, dự kiến ​​4 byte đầu tiên là 0. Đối với 4 byte cuối cùng, chúng ta có thể đảo ngược chúng (vì CPU là phần tử nhỏ) và nhận được 84,96 =01010100 01100000 cơ số 2 =21600 trong hệ thập phân. Việc chuyển đổi 21600 giây thành giờ mang lại cho bạn 6 giờ, đây là sự khác biệt mà chúng tôi mong đợi.

Hy vọng điều này sẽ giúp ích cho những ai đang thắc mắc về cách thực sự lưu trữ một phép trừ DATE.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hướng dẫn từng bước để cài đặt hộp ảo Oracle

  2. Khi nào tôi cần sử dụng dấu chấm phẩy và dấu gạch chéo trong Oracle SQL?

  3. tìm nạp tên bảng từ một cột cho mệnh đề from

  4. Lỗi đầu ra Fiddle SQL

  5. Từ khóa 'CONTINUE' trong Oracle 10g PL / SQL