Oracle stored function - pass table name as parameter

孤街浪徒 提交于 2019-12-24 15:42:29

问题


I'm trying to create a stored function in Oracle that will count the table rows..i want to make the table name dynamic, so i passed it as a parameter, the stored function code looks like this

create type tes_jml_obj is object(jumlah integer);
create type tes_jml_table is table of tes_jml_obj;
create or replace function jumlahBaris(namatabel varchar)
return tes_jml_table
is
  tabel tes_jml_table := tes_jml_table();
begin
  for r in (execute immediate 'select count(*) as jumlah from' || namatabel)
  loop
    tabel.extend;
    tabel(1) := tes_jml_obj(r.jumlah);
  end loop;
  return tabel;
end;

But when i execute it, it returns errors. Am i missing something here? Is that the correct way to get the table rows dynamically?


回答1:


  1. Your execute immediate will return only one value, the count, so what is there to loop over?
  2. Also I'm not sure that execute immediate works with an implicit cursor.
  3. In your SQL it looks like you don't have a space after the from keyword.

Try something like this instead:

create or replace function jumlahBaris(namatabel varchar)
return tes_jml_table
is
  tabel tes_jml_table := tes_jml_table();
  the_count integer;
  the_sql varchar(100);
begin
  the_sql := 'select count(*) as jumlah from ' || namatabel;
  execute immediate the_sql INTO the_count;

  if the_count IS NOT NULL THEN
      tabel.extend;
      tabel(1) := tes_jml_obj(the_count);
  end if;
  return tabel;
end;



回答2:


  1. There is a space missing after FROM keyword in the EXECUTE IMMEDIATE statement.
  2. EXECUTE IMMEDIATE statement has a syntax error. You are missing the INTO clause.
  3. You cannot use EXECUTE IMMEDIATE inside a CURSOR FOR LOOP. Basically, you are returning nothing from the execute immediate statement as mentioned in point 2 above.
  4. The iteration syntax for the LOOP is not correct. The syntax is FOR r IN 1..COUNT().

After rectifying your code, this is how it would look like:

SQL> CREATE OR REPLACE TYPE TES_JML_OBJ IS OBJECT(JUMLAH NUMBER)
  2  /

Type created.

SQL> CREATE OR REPLACE TYPE TES_JML_TABLE IS TABLE OF TES_JML_OBJ
  2  /

Type created.

SQL> CREATE OR REPLACE
  2    FUNCTION jumlahBaris(
  3        namatabel VARCHAR2)
  4      RETURN tes_jml_table
  5    IS
  6      TABEL TES_JML_TABLE := TES_JML_TABLE();
  7      cnt NUMBER;
  8    BEGIN
  9      EXECUTE IMMEDIATE 'select count(*) as jumlah from ' || NAMATABEL INTO CNT;
 10      FOR R IN 1..CNT
 11      LOOP
 12        TABEL.EXTEND;
 13        TABEL(R) := TES_JML_OBJ(R);
 14        dbms_output.put_line(TES_JML_OBJ(R).jumlah);
 15      END LOOP;
 16      RETURN tabel;
 17    END;
 18    /

Function created.

SQL> SHO ERR
No errors.

So, the function compiled with no errors. Let's execute it and see the output:

SQL> SET SERVEROUTPUT ON
SQL> SELECT JUMLAHBARIS('EMP') FROM DUAL;

JUMLAHBARIS('EMP')(JUMLAH)
--------------------------------------------------------------------------------
TES_JML_TABLE(TES_JML_OBJ(1), TES_JML_OBJ(2), TES_JML_OBJ(3), TES_JML_OBJ(4), TE
S_JML_OBJ(5), TES_JML_OBJ(6), TES_JML_OBJ(7), TES_JML_OBJ(8), TES_JML_OBJ(9), TE
S_JML_OBJ(10), TES_JML_OBJ(11), TES_JML_OBJ(12), TES_JML_OBJ(13), TES_JML_OBJ(14
))


1
2
3
4
5
6
7
8
9
10
11
12
13
14
SQL>


来源:https://stackoverflow.com/questions/29958998/oracle-stored-function-pass-table-name-as-parameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!