最近在调试一个带DML操作的函数时,一直不成功,在PL/SQL中测试时没问题,通过SQL语句调用函数时就不行了,刚开始一直没找到原因,后来无意间把 函数中捕获异常的代码注释掉,终于通过SQL调试时,弹出了一个“ORA-14551: 无法在查询中执行 DML 操作 .”错误,找到了问题原因,就好找解决办法了,在网上找到一篇文章,大谈什么自治事务和主事务,看了半天,还是云里雾里,找到关键点,就是添加一条语句“PRAGMA AUTONOMOUS_TRANSACTION;”,并在最后 COMMIT 提交DML操作,问题迎刃而解,至于这个什么自治事务和主事务,还是有时间,后面再慢慢消化了。
----以下是引用文章:
在函数中,往临时表插入数据报错:
ORA-14551: 无法在查询中执行 DML 操作
ORA-06512: 在 "NSTCSA.NS_ST_GETRAISEFUNDX", line 29
增加下面的字符串:
PRAGMA AUTONOMOUS_TRANSACTION;
数据库事务是一种单元操作,要么是全部操作都成功,要么全部失败。在Oracle中,一个事务是从执行第一个数据管理语言(DML)语句开始,直到执行一个COMMIT语句,提交保存这个事务,或者执行一个ROLLBACK语句,放弃此次操作结束。
事务的“要么全部完成,要么什么都没完成”的本性会使将错误信息记入数据库表中变得很困难,因为当事务失败重新运行时,用来编写日志条目的INSERT语句还未完成。
针对这种困境,Oracle提供了一种便捷的方法,即自治事务。自治事务从当前事务开始,在其自身的语境中执行。它们能独立地被提交或重新运行,而不影响正在运行的事务。正因为这样,它们成了编写错误日志表格的理想形式。在事务中检测到错误时,您可以在错误日志表格中插入一行并提交它,然后在不丢失这次插入的情况下回滚主事务。
因为自治事务是与主事务相分离的,所以它不能检测到被修改过的行的当前状态。这就好像在主事务提交之前,它们一直处于单独的会话里,对自治事务来说,它们是不可用的。然而,反过来情况就不同了:主事务能够检测到已经执行过的自治事务的结果。
要创建一个自治事务,您必须在匿名块的最高层或者存储过程、函数、数据包或触发的定义部分中,使用PL/SQL中的PRAGMA AUTONOMOUS_TRANSACTION语句。在这样的模块或过程中执行的SQL Server语句都是自治的。
触发无法包含COMMIT语句,除非有PRAGMA AUTONOMOUS_TRANSACTION标记。但是,只有触发中的语句才能被提交,主事务则不行。
exp:
Create table Msg (Msg varchar(50)) ;
自制事务:
create or replace procedure AutoNomouse_Insert is
PRAGMA AUTONOMOUS_TRANSACTION;
begin
insert into Msg values('AutoNomouse Insert');
commit;
end;
非自治事务:
CREATE OR REPLACE Procedure NonAutoNomouse_Insert as
begin
insert into Msg Values('NonAutonomouse Insert');
commit;
end;
SQL> begin
3            insert into Msg Values('This Main Info');
5            NonAutoNomouse_Insert;
7            rollback;
9  end
10  ;
11  /
PL/SQL procedure successfully completed
SQL> select * from msg;
MSG
--------------------------------------------------
This Main Info
NonAutonomouse Insert
因为过程中有COMMIT;所以匿名块中得RULLBACK 是不起作用的; 由此得出:非自治事务中的COMMIT,ROLLBACK
是会影响整个事务的。
下面我们看一个另外一种情况:
SQL> delete msg;
2 rows deleted
SQL>
这里没有COMMIT;
SQL> begin
3            insert into Msg Values('This Main Info');
5            rollback;  --这里加了ROLLBACK;
7            NonAutoNomouse_Insert;
9            rollback;
10 
11  end
12  ;
13  /
PL/SQL procedure successfully completed
SQL> select * from msg;
MSG
--------------------------------------------------
This Main Info
NonAutonomouse Insert
NonAutonomouse Insert
竟然没有ROLLBACK (DELETE * FROM SSG ;) 为什么了?因为过程就是一个新的SESSION,所以前面的SESSION
被正常EXIT,同时被自动提交; 所以我们会看到三行数据。
SQL> commit;
Commit complete
SQL> select * from msg;
MSG
--------------------------------------------------
This Main Info
NonAutonomouse Insert
NonAutonomouse Insert
SQL> commit;
Commit complete
SQL> select * from msg;
MSG
--------------------------------------------------
This Main Info
NonAutonomouse Insert
NonAutonomouse Insert
因为这里一个新的SESSION 所以是没有意义的事务控制语句。
SQL> delete msg;
3 rows deleted
SQL> commit;
Commit complete
SQL> select * from msg;
MSG
--------------------------------------------------
可以看到这里是正常的提交;
下面看一下自制事务:
SQL> begin
3            insert into Msg Values('This Main Info');
5            AutoNomouse_Insert;
7            rollback;
9  end
10 
11  ;
12  /
PL/SQL procedure successfully completed
SQL> select * from msg;
MSG
--------------------------------------------------
AutoNomouse Insert
我们看到是一行数据,显然第一条SQL INSERT 是被ROLLBACK,证明自制事务是一个独立于主程序的事务,
他不会对主事务的控制产生影响。另外在分布式环境中我们经常会遇到 ORA-02064 ERROR ,就是因为主事务
自己有事务控制语句,然而被调用的远程过程也有自己的事物控制语句,当然就会报错,我们将被调用的过程
声明为自制事务那就OK了。
今天在函数中使用insert语句时,报了ora-14551 无法在查询中执行dml操作错误。
错误的解决办法,有两种:
一、在函数外面套存储过程;
二、使用自治事务(AUTONOMOUS TRANSACTION)
在函数声明部分加入这句话
PRAGMA AUTONOMOUS_TRANSACTION;
我选择了后一种。
参考原文:http://www.cnblogs.com/birdwawe/archive/2012/05/18/2507787.html

http://blog.csdn.net/gigiouter/article/details/7616627

ORA-14551: 无法在查询中执行 DML 操作相关推荐

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

    环境 Oracle 11.2.0 + SQL Plus 问题 根据以下要求编写函数:将scott.emp表中工资低于平均工资的职工工资加上200,并返回修改了工资的总人数.PL/SQL中有更新的操作, ...

  2. 使用SQL数据库在Python中执行CRUD操作

    目录 介绍 背景 在Visual Studio中创建一个Python项目 在SQL中创建数据库和表 为数据库创建配置文件 安装Python包 "Pypyodbc" 创建连接文件 创 ...

  3. 【数据库】请问在 score表中执行以下操作:count( studentNo)、 count( score)、 count( * )、avg( studentNo)、 avg( score)、avg

    题目 请问在 score表中执行以下操作:count( studentNo). count( score). count( * ).avg( studentNo). avg( score).avg( ...

  4. mysql中的dml操作_MySQL操作语言[DML]

    insert操作insert into table_name (field1, field2,...fieldN) values (value1, value2,...valueN);如果ID值设置为 ...

  5. android 按钮中断,android – 如何“中断”在AccessibilityService中执行的操作?

    我想做什么/我做了什么:我正在尝试为视障用户制作一个非常基本的TalkBack版本.我做了一个简单的辅助功能服务,读取用户点击的按钮的contentDescription并大声读出. @Overrid ...

  6. java gridfs_如何在GridFS中执行更新操作(使用Java)?

    我使用的Mongo-Java-Driver 2.13是在 GridFS中 存储了一个PDF文件( 大小 为 30mb) .我能够轻松地执行插入,删除和查找操作. MongoClient mongo = ...

  7. 6-6 调查 :在6.3.1节编写的程序favorite_languages.py中执行以下操作

    创建一个应该会接受调查的人员名单,其中有些人已包含在字典中,而其他人未包含在字典中. 遍历这个人员名单,对于已参与调查的人,打印一条消息表示感谢.对于还未参与调查的人,打印一条消息邀请他参与调查. ​ ...

  8. Oracle存储过程中执行DDL操作

    Create Or Replace Procedure My_Proc As Sqlddl Varchar2(1000); Begin Sqlddl := 'create table MyTable( ...

  9. oracle字段公式怎么执行,Oracle 在存储过程或函数中执行字符串sql PDF 下载

    主要内容: 有时,我们需要在存储过程或函数中根据条件拼凑一些sql字符串语句,然后再执行拼凑后的sql字符串,如何做到呢? 参考以下代码: FUNCTION CALCULATE_TARGET_SCOR ...

最新文章

  1. DEEPIN教程 - 本地安装Typora
  2. php 显示中文utf,php adodb 从mysql数据库中输出中文显示到utf编码网页乱码问题
  3. Javashop电商系统7.0发布
  4. mysql基础01 创建表 修改表
  5. 远比5G发展凶猛!物联网2018白皮书,国内规模已达1.2万亿
  6. 一元云购qq互联回调地址错误解决办法
  7. 3000计算机组装电脑,电脑组装教程,教您组装电脑配置清单
  8. (Emitted value instead of an instance of Error)
  9. Hololens开发学习笔记-4
  10. xinxin- 新鑫牌计算器
  11. Installation failed with message Failed to finalize session : INSTALL_FAILED_INVALID_APK:
  12. SQLSERVER格式化日期时间
  13. Qt数据库应用19-图片转pdf
  14. 电脑端之破解教学详情
  15. mongo: error while loading shared libraries: libcrypto.so.10: cannot open shared object file: No suc
  16. 薄膜干涉、增透膜增反膜、劈尖和牛顿环(大学物理笔记)
  17. File does not exist: /user/anonymous/.staging/job_1628851608378_6064/报错问题解决
  18. 开启我的博客之旅吧!
  19. ICASSP 2022丨希尔贝壳1篇论文被录用
  20. 大数据系统计算的概念全面解析

热门文章

  1. shell发送邮件函数
  2. 【Spark】开发Spark选择Java还是Scala?
  3. 工业智能相机与基于PC的机器视觉的区别比较
  4. linux中echo的使用方法
  5. Linux 高性能服务器编程——多线程编程
  6. gitlab的用户使用手册
  7. linux服务器下降,linux - 远程升级Ubuntu:如何最大程度地降低丢失服务器的风险? - Ubuntu问答...
  8. Caused by: Parent package is not defined: json-default - [unknown location]
  9. 微信视频开发jquery mobile
  10. java手机状态栏圆形图标,android实现状态栏添加图标的函数实例