Oracle存储函数-将表名作为参数传递

Oracle存储函数-将表名作为参数传递,oracle,stored-procedures,plsql,stored-functions,Oracle,Stored Procedures,Plsql,Stored Functions,我试图在Oracle中创建一个存储函数来计算表行数。我想使表名成为动态的,所以我将其作为参数传递,存储函数代码如下所示 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 tabe

我试图在Oracle中创建一个存储函数来计算表行数。我想使表名成为动态的,所以我将其作为参数传递,存储函数代码如下所示

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;
但当我执行它时,它会返回错误。我是不是遗漏了什么?这是动态获取表行的正确方法吗

  • 您的executeimmediate将只返回一个值,count,那么有什么可以循环呢
  • 另外,我不确定executeimmediate是否能与隐式游标一起工作
  • 在SQL中,关键字
    from
    后面似乎没有空格
  • 请尝试以下方法:

    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;
    
  • 您的executeimmediate将只返回一个值,count,那么有什么可以循环呢
  • 另外,我不确定executeimmediate是否能与隐式游标一起工作
  • 在SQL中,关键字
    from
    后面似乎没有空格
  • 请尝试以下方法:

    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;
    
  • executeimmediate语句中的FROM关键字后缺少空格
  • executeimmediate语句有语法错误。您缺少INTO子句中的
  • 不能在循环的光标内使用EXECUTE IMMEDIATE。基本上,您是从上面第2点提到的executeimmediate语句中不返回任何内容
  • 循环迭代语法不正确。1..COUNT()中r的语法为
  • 更正代码后,情况如下:

    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.
    
    因此,函数编译时没有错误。让我们执行它并查看输出:

    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>
    
  • executeimmediate语句中的FROM关键字后缺少空格
  • executeimmediate语句有语法错误。您缺少INTO子句中的
  • 不能在循环的光标内使用EXECUTE IMMEDIATE。基本上,您是从上面第2点提到的executeimmediate语句中不返回任何内容
  • 循环迭代语法不正确。1..COUNT()中r的语法为
  • 更正代码后,情况如下:

    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.
    
    因此,函数编译时没有错误。让我们执行它并查看输出:

    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>
    

    你会犯什么错误。您肯定也总是想发布错误。我不一定认为这是问题所在,但为了安全起见,您可以将带有连接的sql字符串放在参数中:
    (execute immediate('select count(*)as jumlah from'| | namatabel))
    。另外,在的
    后面加一个空格(这可能是个问题)。对不起,我的错。。以下是错误(6,21):PLS-00103:在预期以下情况之一时遇到符号“立即”:。(),*@%&=-+在in处是模余数而不是rem=>或!=或者~=>=您会遇到什么错误。您肯定也总是想发布错误。我不一定认为这是问题所在,但为了安全起见,您可以将带有连接的sql字符串放在参数中:
    (execute immediate('select count(*)as jumlah from'| | namatabel))
    。另外,在
    后面加一个空格(这可能是个问题)。对不起,我的错。。以下是错误(6,21):PLS-00103:在预期以下情况之一时遇到符号“立即”:。(),*@%&=-+在in处是模余数而不是rem=>或!=或者~=>=我又坏了,谢谢你提醒我:)但是错误还是一样的,在我运行它之后,“执行”和“立即”之间有一条红色下划线。你认为这是错误吗?嗯。。我试图将“for循环”替换为“if”,但仍然没有成功:(请参阅我的更新。我肯定认为光标在使用“立即执行”时可能会有问题。工作起来很有魅力!!谢谢!但是你错过了“如果结束”的位置:)我的错误再次出现,谢谢你提醒我:)但是错误仍然相同,并且中间有一条红色下划线在我运行它之后,“执行”和“立即执行”。你认为这是错误吗?嗯……我试图用“如果”替换“for循环”,但仍然没有成功:(请参阅我的更新。我肯定认为光标在使用“执行立即执行”时可能有问题。工作起来很有魅力!!谢谢!但是你错过了那里的“如果结束”: