oracle 查询执行过的dml,PL/SQL“ ORA-14551: 无法在查询中执行 DML 操作”解决

环境

Oracle 11.2.0 + SQL Plus

问题

根据以下要求编写函数:将scott.emp表中工资低于平均工资的职工工资加上200,并返回修改了工资的总人数。PL/SQL中有更新的操作,执行此函数报如下错误:ORA-16551: 无法在查询中执行 DML 操作。

d17e2edbb0e710b16fc552daa947a587.png

解决

在声明函数时加上: PRAGMA AUTONOMOUS_TRANSACTION; 并在执行完DML后COMMIT。

操作日志

--登录到Oracle

C:\Users\Wentasy>sqlplus wgb

SQL*Plus: Release 11.2.0.1.0 Production on 星期六 6月 29 15:32:21 2013

Copyright (c) 1982, 2010, Oracle.  All rights reserved.

输入口令:

连接到:

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

With the Partitioning, OLAP, Data Mining and Real Application Testing options

--编写函数

SQL> CREATE OR REPLACE FUNCTION raise_sal

2  RETURN NUMBER

3  IS

4  v_num NUMBER:=0;

5  v_avg emp.sal%TYPE;

6  BEGIN

7    SELECT AVG(sal) INTO v_avg FROM emp;

8    UPDATE emp SET sal=sal+200 WHERE sal < v_avg;

9    v_num:=SQL%ROWCOUNT;

10    RETURN v_num;

11  END raise_sal;

12  /

函数已创建。

--调用函数,出现错误

SQL> SELECT raise_sal() FROM DUAL;

SELECT raise_sal() FROM DUAL

*

第 1 行出现错误:

ORA-14551: 无法在查询中执行 DML 操作

ORA-06512: 在 "WGB.RAISE_SAL", line 8

--加上PRAGMA AUTONOMOUS_TRANSACTION和COMMIT。

SQL> CREATE OR REPLACE FUNCTION raise_sal

2  RETURN NUMBER

3  IS

4  PRAGMA AUTONOMOUS_TRANSACTION;

5  v_num NUMBER:=0;

6  v_avg emp.sal%TYPE;

7  BEGIN

8    SELECT AVG(sal) INTO v_avg FROM emp;

9    UPDATE emp SET sal=sal+200 WHERE sal < v_avg;

10    v_num:=SQL%ROWCOUNT;

11    COMMIT;

12    RETURN v_num;

13  END raise_sal;

14  /

函数已创建。

--验证第一步:查询薪水平均值

SQL> SELECT AVG(sal) FROM emp;

AVG(SAL)

----------

2543.75

--验证第二步:查询薪水比平均薪水低的员工的总数

SQL> SELECT count(sal) FROM emp WHERE sal < (SELECT AVG(sal) FROM emp);

COUNT(SAL)

----------

8

--验证第三步:查询数据

SQL> SELECT ename, sal FROM emp;

ENAME            SAL

---------- ----------

SMITH            1600

ALLEN            2400

WARD            2050

JONES            2975

MARTIN          2050

BLAKE            2850

CLARK            2450

KING            5000

TURNER          2300

JAMES            1750

FORD            3000

ENAME            SAL

---------- ----------

MILLER          2100

已选择12行。

--验证第四步:调用函数,如果为8,则实现功能

SQL> SELECT raise_sal() FROM dual;

RAISE_SAL()

-----------

8

--验证第五步:再次查询表数据

SQL> SELECT ename, sal FROM emp;

ENAME            SAL

---------- ----------

SMITH            1800

ALLEN            2600

WARD            2250

JONES            2975

MARTIN          2250

BLAKE            2850

CLARK            2650

KING            5000

TURNER          2500

JAMES            1950

FORD            3000

ENAME            SAL

---------- ----------

MILLER          2300

已选择12行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值