Prosedur umum yang dapat menjalankan prosedur/fungsi apa pun

input
Nama paket (IN)
nama prosedur (atau nama fungsi) (IN)
Tabel yang diindeks dengan bilangan bulat, akan berisi nilai yang akan digunakan untuk menjalankan prosedur (MASUK/ KELUAR).

Misalnya
mari kita asumsikan bahwa kita ingin menjalankan prosedur di bawah ini

utils.get_emp_num(emp_name IN VARCHAR
                  emp_last_name IN VARCHAR
                  emp_num OUT NUMBER
                  result  OUT VARCHAR);

Prosedur yang akan kita buat akan memiliki masukan:

package_name = utils
procedure_name = get_emp_num
table = T[1] -> name
        T[2] -> lastname
        T[3] -> 0   (any value) 
        T[4] -> N   (any value)

run_procedure(package_name,
              procedure_name,
              table)

Prosedur utama harus mengembalikan tabel yang sama yang telah ditetapkan pada input, tetapi dengan hasil eksekusi prosedur

table =  T[1] -> name
         T[2] -> lastname
         T[3] -> 78734 (new value)
         T[4] -> F     (new value)

ada pemikiran?


person Messady    schedule 19.09.2013    source sumber
comment
Sepertinya Anda telah menemukan solusi pada saat Anda seharusnya menjelaskan masalah Anda. Saya tidak dapat membayangkan ini adalah cara yang baik untuk mengeksekusi apa pun... jadi, apa masalah Anda?   -  person Ben    schedule 20.09.2013
comment
Skrip Lua akan memanggil fungsi Pro*c yang akan menjalankan prosedur dan mengembalikan tabel data (hasilnya) ke fungsi Lua untuk digunakan lebih lanjut. Saya tidak menemukan cara yang lebih baik untuk mendapatkan hasil prosedur dari skrip Lua.   -  person Messady    schedule 20.09.2013
comment
Ya, tapi apakah Anda perlu memanggil setiap prosedur menggunakan panggilan yang sama persis. Mungkin lebih normal untuk mengubah panggilan Pro*C Anda tergantung pada prosedur yang Anda perlukan untuk memanggil daripada mengubah database untuk memanggil semuanya secara identik.   -  person Ben    schedule 20.09.2013
comment
Proc adalah bahasa yang dikompilasi, Proc akan berisi pemrosesan utama untuk semua pengguna (sama), sedangkan skrip Lua akan digunakan sebagai plugin (tergantung pengguna, akan bervariasi ), skrip akan berupa file .Lua sederhana (bukan biner) dan akan dipanggil hanya dengan memberikan PATH ke program Proc. Hal ini untuk menghindari pemberian versi kode Pro*c tertentu kepada setiap pengguna, dan memungkinkan skrip Lua menjalankan prosedur/fungsi apa pun tanpa mengubah kode Pro*C.   -  person Messady    schedule 20.09.2013


Jawaban (2)


Anda dapat mencapainya dengan EXECUTE IMMEDIATE. Pada dasarnya, Anda membuat pernyataan SQL dalam bentuk berikut:

sql := 'BEGIN utils.get_emp_num(:1, :2, :3, :4); END;';

Kemudian Anda menjalankannya:

EXECUTE IMMEDIATE sql USING t(1), t(2), OUT t(3), OUT t(4);

Sekarang inilah bagian yang sulit: Untuk setiap jumlah parameter dan kombinasi IN/OUT Anda memerlukan pernyataan EXECUTE IMMEDIATE yang terpisah. Dan untuk mengetahui jumlah parameter dan arahnya, Anda perlu menanyakan tabel ALL_ARGUMENTS terlebih dahulu.

Anda mungkin dapat menyederhanakannya dengan meneruskan seluruh tabel sebagai argumen pengikat, bukan argumen pengikat terpisah untuk setiap elemen tabel. Tapi saya belum tahu bagaimana Anda akan melakukan itu.

Dan hal berikutnya yang harus Anda pertimbangkan: elemen tabel T yang Anda gunakan akan memiliki tipe: VARCHAR, NUMBER, dll. Jadi campuran saat ini di mana Anda memiliki angka dan string tidak akan berfungsi.

BTW: Mengapa Anda menginginkan mekanisme panggilan dinamis seperti itu?

person Codo    schedule 19.09.2013
comment
Pengguna dapat menulis skrip Lua miliknya sendiri, dan meminta data dari DB, Lua akan memanggil fungsi PRO*C yang akan menjalankan prosedur dan mengembalikan hasilnya (tabel) ke skrip Lua. Saya diminta untuk melakukan pemikiran yang sama, membuat prosedur yang memungkinkan eksekusi kueri apa pun, mudah dilakukan dengan menggunakan paket DBMS_SQL, tetapi dengan prosedur/fungsi menurut saya ini lebih rumit. - person Messady; 20.09.2013

Dapatkan dari tabel all_arguments nama_argumen, tipe_data, masuk_keluar, dan posisinya

Bangun blok PLSQL

DECLARE
    loop over argument_name and create the declare section
    argument_name data_type if in_out <> OUT then := VALUE OF THE INPUT otherwise NULL
BEGIN

--In the case of function create an additional argument 
function_var:= package_name.procedure_name( loop over argument_name);

--use a table of any_data, declare it as global in the package

if function then
    package_name.ad_table.EXTEND;
    package_name.ad_table(package_name.ad_table.LAST):= function_var;
end if

--loop over argument_name IF IN_OUT <> IN
package_name.ad_table.EXTEND;
package_name.ad_table(package_name.ad_table.LAST):= 

if data_type = VARCHAR2 then := ConvertVarchar2(argument_name)
else if NUMBER then ConvertNumber 
else if DATE then ConvertDate
...

END;

Hasilnya disimpan dalam tabel. Untuk mendapatkan nilai, gunakan fungsi Access*

person Messady    schedule 10.10.2013