Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Abaikan parameter rentang tanggal di klausa where saat parameter tidak dimasukkan

Anda memiliki dua kemungkinan untuk mendekati parameter input opsional.

lebih sederhana caranya adalah dengan menggunakan SQL statis dan menyediakan default nilai untuk parameter yang hilang, sehingga Anda mendapatkan semua kecocokan.

Di sini Anda dapat dengan mudah menetapkan batas ke DATE minimum dan maksimum yang mungkin.

select * 
from customer
where customer_id = $P{CLIENT_ID}
and datetrx between nvl($P{DATE_START},date'1900-01-01') 
                and nvl($P{DATE_END},date'2200-01-01')

Semakin maju way dipopulerkan oleh Tom Kyte dan didasarkan pada penggunaan SQL dinamis.

Jika parameter disediakan , Anda membuat SQL normal dengan BETWEEN predikat :

select * 
from customer
where customer_id = $P{CLIENT_ID}
and datetrx between $P{DATE_START} and $P{DATE_END}

Jika parameter tidak ada (yaitu NULL dilewatkan) Anda menghasilkan SQL yang berbeda seperti yang ditunjukkan di bawah ini.

select * 
from customer
where customer_id = $P{CLIENT_ID}
and (1=1 or datetrx between $P{DATE_START} and $P{DATE_END})

Perhatikan, bahwa

1) jumlah variabel ikat sama di kedua varian kueri, yang penting karena Anda dapat menggunakan setXXXX yang identik pernyataan

2) karena jalan pintas 1 = 1 or adalah between predikat diabaikan, yaitu semua tanggal dianggap.

Opsi mana yang harus digunakan?

Nah untuk kueri sederhana akan ada sedikit perbedaan, tetapi untuk kueri kompleks dengan beberapa opsi parameter yang hilang dan data yang besar, pendekatan SQL dinamis lebih disukai .

Alasannya adalah, menggunakan SQL statis Anda menggunakan pernyataan yang sama untuk kueri yang lebih berbeda - ini satu untuk mengakses dengan rentang data dan satu untuk akses tanpa rentang data.

Opsi dinamis menghasilkan SQL yang berbeda untuk setiap akses.

Anda dapat melihatnya di rencana eksekusi:

Akses dengan rentang tanggal

-------------------------------------------------------------------------------
| Id  | Operation         | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |           |     1 |    22 |     1   (0)| 00:00:01 |
|*  1 |  FILTER           |           |       |       |            |          |
|*  2 |   INDEX RANGE SCAN| CUST_IDX1 |     1 |    22 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------

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

   1 - filter(TO_DATE(:1)<=TO_DATE(:2))
   2 - access("CUSTOMER_ID"=1 AND "DATETRX">=:1 AND "DATETRX"<=:2)

Akses tanpa rentang data

------------------------------------------------------------------------------
| Id  | Operation        | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |           |     1 |    22 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| CUST_IDX1 |     1 |    22 |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------


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

   1 - access("CUSTOMER_ID"=1)

Kedua pernyataan menghasilkan rencana eksekusi yang berbeda, yang dioptimalkan untuk parameter input. Dalam penggunaan opsi statis harus berbagi rencana eksekusi yang sama untuk semua masukan yang dapat menyebabkan masalah.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Durasi data dalam tabel Sementara Global?

  2. Zip menggunakan Oracle Stored Procedure

  3. Oracle DB:Bagaimana saya bisa menulis kasus pengabaian kueri?

  4. Perbarui permintaan jika pernyataan untuk Oracle

  5. Tentang Elemen Format RM di Oracle