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

sử dụng hoặc trong mệnh đề where cho vấn đề cột loại ngày khi so sánh với sysdate trong Oracle

Tôi có thể sao chép nó và lý do đằng sau hành vi đó là cách giải thích các vị từ của Oracle.

Phiên bản của hệ điều hành và Oracle nơi có thể sao chép điều này:

SQL> host ver

Microsoft Windows [Version 6.1.7601]

SQL> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for 64-bit Windows: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

SQL>

Trong trường hợp đầu tiên, vị từ được sửa đổi thành filter("D"."DT" IS NOT NULL) trong khi ở truy vấn thứ hai, vị từ hoạt động như bộ lọc filter("D"."DT"<TO_DATE(' 2013-01-20 00:00:00', 'syyyy-mm-dd hh24:mi:ss') OR "D"."DT">[email protected]!)

SQL> select count(*)
  2  from aaa d
  3  where (d.dt > sysdate)
  4  or d.dt < to_date('20130120','yyyymmdd')
  5  /

  COUNT(*)
----------
        15

Execution Plan
----------------------------------------------------------
Plan hash value: 977873394

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |     9 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |      |     1 |     9 |            |          |
|*  2 |   TABLE ACCESS FULL| AAA  |    15 |   135 |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("D"."DT" IS NOT NULL)

Note
-----
   - dynamic sampling used for this statement (level=2)


Statistics

----------------------------------------------------------
      4  recursive calls
      0  db block gets
     15  consistent gets
      0  physical reads
      0  redo size
    346  bytes sent via SQL*Net to client
    364  bytes received via SQL*Net from client
      2  SQL*Net roundtrips to/from client
      0  sorts (memory)
      0  sorts (disk)
      1  rows processed

SQL> ed
Wrote file afiedt.buf

  1  select count(*)
  2  from aaa d
  3  where d.dt < to_date('20130120','yyyymmdd')
  4* or (d.dt > sysdate)
SQL> 
/

  COUNT(*)
----------
         7

Execution Plan
----------------------------------------------------------
Plan hash value: 977873394

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |     9 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |      |     1 |     9 |            |          |
|*  2 |   TABLE ACCESS FULL| AAA  |     7 |    63 |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("D"."DT"<TO_DATE(' 2013-01-20 00:00:00', 'syyyy-mm-dd
              hh24:mi:ss') OR "D"."DT">[email protected]!)

Note
-----
   - dynamic sampling used for this statement (level=2)

Statistics

----------------------------------------------------------
      4  recursive calls
      0  db block gets
     15  consistent gets
      0  physical reads
      0  redo size
    346  bytes sent via SQL*Net to client
    364  bytes received via SQL*Net from client
      2  SQL*Net roundtrips to/from client
      0  sorts (memory)
      0  sorts (disk)
      1  rows processed

SQL>

Tôi không thể tìm ra hành vi này của Oracle, rất có thể một số chuyên gia có thể giải thích điều này.

Một lần nữa trong ví dụ thứ ba, các vị từ được sử dụng chính xác. filter("D"."DT"<TO_DATE(' 2013-01-20 00:00:00', 'syyyy-mm-dd hh24:mi:ss') OR INTERNAL_FUNCTION("D"."DT")+1>[email protected]!+1)

SQL> ed
Wrote file afiedt.buf

  1  select count(*)
  2  from aaa d
  3  where (d.dt + 1 > sysdate + 1)
  4* or d.dt < to_date('20130120','yyyymmdd')
SQL> /

  COUNT(*)
----------
         7

Execution Plan
----------------------------------------------------------
Plan hash value: 977873394

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |     9 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |      |     1 |     9 |            |          |
|*  2 |   TABLE ACCESS FULL| AAA  |     7 |    63 |     3   (0)| 00:00:01 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("D"."DT"<TO_DATE(' 2013-01-20 00:00:00', 'syyyy-mm-dd
              hh24:mi:ss') OR INTERNAL_FUNCTION("D"."DT")+1>[email protected]!+1)

Note
-----
   - dynamic sampling used for this statement (level=2)


Statistics
----------------------------------------------------------
          5  recursive calls
          0  db block gets
         15  consistent gets
          0  physical reads
          0  redo size
        346  bytes sent via SQL*Net to client
        364  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL>

Rõ ràng là nó không thể được sao chép lại từ phiên bản Oracle 11.2.0.2.0 và 11.2.0.3.0 trên máy chủ Linux.

Cập nhật:

Với tư cách là Alex Poole được đề cập trong các nhận xét - "Đây có thể là lỗi 9495697," Kết quả sai có thể được trả về cho truy vấn chứa hai vị từ bộ lọc OR'd trên cùng một cột, trong đó phía bên kia của một vị từ không phải là hằng số thời gian biên dịch (ví dụ:. Nó là một ràng buộc, ngày mã hóa, v.v.) "




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ODP.NET Làm thế nào để chuyển mảng chuỗi vào một thủ tục được lưu trữ trong Oracle?

  2. Biểu thức chính quy (RegEx) cho IPv6 Tách biệt với IPv4

  3. Tạo chế độ xem Oracle với ID được tạo cơ sở dữ liệu từ Đối tượng trình tự

  4. Từ XML đến danh sách các đường dẫn trong môi trường Oracle PL / SQL

  5. Thêm tham số ngày vào truy vấn oracle