调用存储过程内部的"函数"

dim*_*mba 1 sql oracle

我有一个包含大量INSERT的大型存储过程.有许多INSERTS几乎相同 - 它们因某些参数而不同(所有INSERT到同一个表)

有没有办法创建一个函数/方法,我将传递上述参数,函数/方法将生成具体的INSERT?

谢谢

APC*_*APC 5

当然.创建私有函数很容易.

create or replace procedure p1 as

    n pls_integer;

    function private_f return number is
    begin
        return n;
    end private_f;
begin
    n := private_f;
end p1;
Run Code Online (Sandbox Code Playgroud)

需要注意的是私有过程和函数定义必须是declare块中的最后一个声明.也就是说,我们不能在私有函数和外部过程的begin子句之间声明任何变量.

我没有向您展示如何实现将行插入表中的私有函数.那是因为这是一种糟糕的做事方式.在基于集合的方式中使用SQL更有效.

你没有说出参数的来源,所以我会做些什么.

工作的例子

此过程模拟ETL过程.它从登台表中获取一些数据并将其挂载到PL/SQL集合中.然后它以某种方式操作加载的数据,然后使用批量插入语句将数据放入目标表中.

SQL> create or replace procedure pop_emps
  2      ( p_mgr in emp.mgr%type)
  3  as
  4      type emp_nt is table of emp%rowtype;
  5      new_emps emp_nt;
  6  begin
  7      --  populate array from staging table
  8      select emp_seq.nextval
  9             , t.ename
 10             , t.job
 11             , p_mgr
 12             , trunc(sysdate)
 13             , t.sal
 14             , null
 15             , t.deptno
 16      bulk collect into new_emps
 17      from emp_import t;
 18      -- fix some special values
 19      for i in new_emps.first..new_emps.last
 20      loop
 21          if new_emps(i).deptno = 50
 22          then
 23              new_emps(i).job := 'PLUMBER';
 24              new_emps(i).mgr := 8061;
 25          end if;
 26      end loop;
 27      --  insert new rows into EMP table
 28      forall j in new_emps.first..new_emps.last
 29          insert into emp
 30              values new_emps(j);
 31  end  pop_emps;
 32  /

Procedure created.

SQL>
Run Code Online (Sandbox Code Playgroud)

请注意,FORALL是一个设置操作而不是循环.

无论如何,为了显示它的工作,我将加载这三行......

SQL> select * from emp_import
  2  /

ENAME                       SAL     DEPTNO JOB
-------------------- ---------- ---------- --------------------
KESTELYN                   3500         30 MARKETING
LIRA                       3750         30 MARKETING
TRICHLER                   3500         50 MARKETING

SQL> exec pop_emps(7839)

PL/SQL procedure successfully completed.

SQL> select * from emp where hiredate = trunc(sysdate)
  2  /

     EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      8083 KESTELYN   MARKETING       7839 08-APR-10       3500                    30
      8084 LIRA       MARKETING       7839 08-APR-10       3750                    30
      8085 TRICHLER   PLUMBER         8061 08-APR-10       3500                    50

SQL>
Run Code Online (Sandbox Code Playgroud)

编辑2

如果你真的想做私有函数,那么你可以传递%ROWTYPE作为参数....

create or replace procedure pop_emps is
    new_row emp%rowtype;
    procedure pop_emp_row
        ( p_row in emp%rowtype)
    is 
    begin
        insert into emp
            values p_row;
    end pop_emp_row;
begin

    -- assign some values to new_row
    new_row.empno := emp_seq.nextval;
    new_row.ename := 'WHOEVER';
    new_row.hiredate := trunc(sysdate);
    -- etc, etc

    pop_emp_row(new_row);
end  pop_emps;
/
Run Code Online (Sandbox Code Playgroud)