例:函数 f_test(传入参数:人员编号) ,返回值:工资额
应用:select 员工表.员工姓名,f_test(员工表.人员编号) from 员工表;
函数中算法比较复杂,因此用到了临时表,也就有了DML操作
原系统是sqlserver的,如此应用没有问题,转到oracle后,这样应用就不行了,因为如果有select外壳,那内部是不允许进行dml操作的,因为函数的传入参数与select语句相关,函数里面不用临时表解决起来也实在是麻烦,有什么办法能解决这个问题?

解决方案 »

  1.   

    是有临时表。主要是在应用的时候,一般都是 
    select 员工表.员工姓名,f_test(员工表.人员编号) from 员工表;
    这样就等于在 f_test之外加了个select的壳,而在oracle中,select 壳内是不允许DML操作的,也就是说不允许存在delete\insert\update操作,(大家可以试试,会报DML错误)。而我的函数因为过于复杂,离不开临时表,有临时表就肯定会有DML操作。
    我的意思是针对这种情况,不知道有没有什么好的解决方案。谢谢!
      

  2.   

    把"f_test"写成一个函数就可以了,该函数可以进行DML操作的
      

  3.   

    函数和存储过程都支持dml吧 单纯的sql不支持
      

  4.   

    大伙看看顶楼咯。
    是在数据库中建立了一个函数,这个函数里面有DML操作,然后在开发工具中使用了例如:
    select 员工表.员工姓名,f_test(员工表.人员编号) from 员工表;
    这样的语句,在sqlserver中是允许select壳内有DML操作的,在oracle中就会报DML错误,如何解决这样的问题?
      

  5.   

    SQL> create table t_test_dml
      2  (id number,
      3  name varchar2(10));
     
    Table created
     
    SQL> 
    SQL> create or replace function f_get_cnt return number
      2  as
      3  PRAGMA AUTONOMOUS_TRANSACTION;
      4  v_num number;
      5  begin
      6  insert into t_test_dml
      7  values(1,to_char(sysdate,'hh24miss'));
      8  commit;
      9  select count(*) into v_num from t_test_dml;
     10  return v_num;
     11  end ;
     12  /
     
    Function created
     
    SQL> truncate table t_test_dml;
     
    Table truncatedSQL> select  f_get_cnt from dual;
     
     F_GET_CNT
    ----------
             1
     
    SQL> select  f_get_cnt from dual;
     
     F_GET_CNT
    ----------
             2
     
    SQL>
      

  6.   

    PL/SQL函数中有DML操作的话,在select 该函数时,会报(不允许dml操作)错,不过在命令行执行没问题。
      

  7.   


    很感谢,意思是函数中如果有DML操作的话,只要加上提交或回滚就OK了?
    那么顺带出另一个问题,不知道这样的提交或回滚,假若我在开发工具中将包括这个函数之内的多个操作在一个事务中执行,那么执行到这个函数时,会不会对我在开发工具中的事务逻辑打乱?
      

  8.   

    PRAGMA AUTONOMOUS_TRANSACTION;
    估计你没看到这句编译提示