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

jalankan kueri SQL yang disimpan dalam tabel

Ini tampaknya merupakan persyaratan yang sangat aneh, dan yang akan sulit untuk diselesaikan dengan cara yang kuat. STMT_OR_VALUE adalah perwujudan dari anti-pola Satu Kolom Dua Penggunaan. Selanjutnya, menyelesaikan STMT_OR_VALUE membutuhkan logika kontrol aliran dan penggunaan SQL dinamis. Akibatnya itu tidak bisa menjadi solusi SQL murni:Anda perlu menggunakan PL/SQL untuk merakit dan menjalankan kueri dinamis.

Berikut adalah bukti konsep untuk solusi. Saya telah memilih fungsi yang dapat Anda panggil dari SQL. Itu tergantung pada satu asumsi:setiap string kueri yang Anda masukkan ke TEST1.STMT_OR_VALUE memiliki proyeksi kolom numerik tunggal dan setiap string nilai adalah CSV data numerik saja . Dengan ketentuan ini, mudah untuk membuat fungsi yang menjalankan kueri dinamis atau menandai string menjadi serangkaian angka; keduanya dikumpulkan secara massal ke dalam tabel bersarang:

create or replace function get_ids (p_name in test1.name%type) 
  return sys.odcinumberlist
is
  l_rec test1%rowtype;
  return_value sys.odcinumberlist;
begin

  select * into l_rec
  from test1
  where name = p_name;

  if l_rec.type = 'SQL_QUERY' then 
    -- execute a query
    execute immediate l_rec.stmt_or_value
      bulk collect into return_value;
  else
    -- tokenize a string
    select xmltab.tkn
    bulk collect into return_value
    from ( select l_rec.stmt_or_value from dual) t
        , xmltable(  'for $text in ora:tokenize($in, ",") return $text'
                      passing stmt_or_value as "in"
                      columns tkn number path '.'
                   ) xmltab;
  end if;
  return return_value;
end;
/

Perhatikan bahwa ada lebih dari satu cara untuk mengeksekusi pernyataan SQL dinamis dan banyak cara untuk menandai CSV menjadi serangkaian angka. Keputusan saya bersifat arbitrer:silakan ganti metode pilihan Anda di sini.

Fungsi ini dapat dipanggil dengan table() hubungi:

select * 
from data
where id in ( select * from table(get_ids('first'))) -- execute query
or    id in ( select * from table(get_ids('second'))) -- get string of values
/

Manfaat besar dari pendekatan ini adalah merangkum logika seputar evaluasi STMT_OR_VALUE dan menyembunyikan penggunaan SQL Dinamis. Akibatnya mudah untuk menggunakannya dalam pernyataan SQL apa pun sambil mempertahankan keterbacaan, atau untuk menambahkan mekanisme lebih lanjut untuk menghasilkan satu set ID.

Namun, solusi ini rapuh. Ini hanya akan berfungsi jika nilai dalam test1 meja mematuhi aturan. Artinya, tidak hanya harus dapat dikonversi ke aliran nomor tunggal tetapi pernyataan SQL harus valid dan dapat dieksekusi oleh EXECUTE IMMEDIATE. Misalnya, tanda titik koma di data sampel pertanyaan tidak valid dan akan menyebabkan EXECUTE IMMEDIATE terlempar. SQL dinamis paling sulit karena mengubah kesalahan kompilasi menjadi kesalahan runtime.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara mengonfigurasi c3p0 dalam hibernasi untuk memperbarui koneksi DB yang basi secara otomatis

  2. Fungsi jendela SORT mahal, bisakah kita mengatasinya?

  3. Memisahkan baris ke kolom di Oracle

  4. Bagaimana saya bisa melakukan agregat ini?

  5. Bagaimana cara mengatasi pelanggaran batasan unik?