您的位置:首页 > 数据库

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

2014-07-31 11:12 573 查看
环境

Oracle 11.2.0 + SQL Plus

问题

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



解决

在声明函数时加上: 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行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ocp ocm oracle学习
相关文章推荐