it-swarm-id.com

Menggunakan variabel bind dengan klausa SELECT INTO dinamis dalam PL/SQL

Saya punya pertanyaan tentang di mana variabel pengikat dapat digunakan dalam pernyataan SQL dinamis dalam PL/SQL.

Misalnya, saya tahu ini valid:

CREATE OR REPLACE FUNCTION get_num_of_employees (p_loc VARCHAR2, p_job VARCHAR2) 
RETURN NUMBER
IS
  v_query_str VARCHAR2(1000);
  v_num_of_employees NUMBER;
BEGIN
  v_query_str := 'SELECT COUNT(*) FROM emp_' 
                 || p_loc
                 || ' WHERE job = :bind_job';                           
  EXECUTE IMMEDIATE v_query_str
    INTO v_num_of_employees
    USING p_job;
  RETURN v_num_of_employees;
END;
/

Saya bertanya-tanya apakah Anda bisa menggunakan variabel bind dalam pernyataan pilih seperti ini

CREATE OR REPLACE FUNCTION get_num_of_employees (p_loc VARCHAR2, p_job VARCHAR2) 
RETURN NUMBER
IS
  v_query_str VARCHAR2(1000);
  v_num_of_employees NUMBER;
BEGIN
  v_query_str := 'SELECT COUNT(*) INTO :into_bind FROM emp_' 
                 || p_loc
                 || ' WHERE job = :bind_job';                           
  EXECUTE IMMEDIATE v_query_str
    USING out v_num_of_employees, p_job;
  RETURN v_num_of_employees;
END;
/

Catatan saya menggunakan pernyataan SELECT INTO sebagai string dyamic saya dan menggunakan variabel bind di klausa INTO.

Saya sedang bepergian sekarang dan tidak akan memiliki akses ke komputer saya di rumah selama beberapa hari, tetapi ini telah mengganggu saya sedikit. Sudah mencoba membaca referensi PL/SQL tetapi mereka tidak memiliki contoh pilih seperti ini.

Terima kasih

42
BYS2

Tidak, Anda tidak dapat menggunakan variabel bind dengan cara itu. Dalam contoh kedua Anda :into_bind di v_query_str hanyalah placeholder untuk nilai variabel v_num_of_employees. Pernyataan pilih menjadi Anda akan berubah menjadi seperti:

SELECT COUNT(*) INTO  FROM emp_...

karena nilai v_num_of_employees adalah null di EXECUTE IMMEDIATE.

Contoh pertama Anda menyajikan cara yang benar untuk mengikat nilai kembali ke variabel.

Edit

Poster asli telah mengedit blok kode kedua yang saya maksudkan dalam jawaban saya untuk menggunakan mode parameter OUT untuk v_num_of_employees alih-alih mode IN default. Modifikasi ini membuat kedua contoh setara secara fungsional.

27
user272735

Menurut pendapat saya, blok PL/SQL dinamis agak tidak jelas. Meskipun sangat fleksibel, juga sulit untuk ditala, sulit untuk debug dan sulit untuk mencari tahu apa yang terjadi .. Pilihan saya adalah pilihan pertama Anda,

EXECUTE IMMEDIATE v_query_str INTO v_num_of_employees USING p_job;

Keduanya menggunakan variabel bind, tetapi pertama-tama, bagi saya, lebih bisa ditiru dan disetel daripada opsi @jonearles. 

27
Aitor

Masukkan pernyataan pilih dalam blok PL/SQL dinamis.

CREATE OR REPLACE FUNCTION get_num_of_employees (p_loc VARCHAR2, p_job VARCHAR2) 
RETURN NUMBER
IS
  v_query_str VARCHAR2(1000);
  v_num_of_employees NUMBER;
BEGIN
  v_query_str := 'begin SELECT COUNT(*) INTO :into_bind FROM emp_' 
                 || p_loc
                 || ' WHERE job = :bind_job; end;';
  EXECUTE IMMEDIATE v_query_str
    USING out v_num_of_employees, p_job;
  RETURN v_num_of_employees;
END;
/
18
Jon Heller

Bind variabel dapat digunakan dalam permintaan Oracle SQL dengan klausa "in".

Bekerja dalam 10g; Saya tidak tahu tentang versi lain.

Variabel terikat adalah varchar hingga 4000 karakter.

Contoh: Variabel terikat yang berisi daftar nilai yang dipisah koma, mis.

: bindvar = 1,2,3,4,5 

select * from mytable
  where myfield in
    (
      SELECT regexp_substr(:bindvar,'[^,]+', 1, level) items
      FROM dual
      CONNECT BY regexp_substr(:bindvar, '[^,]+', 1, level) is not null
    );

(Info yang sama seperti yang saya posting di sini: Bagaimana Anda menentukan klausa IN dalam permintaan dinamis menggunakan variabel? )

0
Kat