黑龙江网站备案查询,腾龙官方网站做号软件,在线网站生成器,昆明网页建站平台最近在调试一个带DML操作的函数时#xff0c;一直不成功#xff0c;在PL/SQL中测试时没问题#xff0c;通过SQL语句调用函数时就不行了#xff0c;刚开始一直没找到原因#xff0c;后来无意间把 函数中捕获异常的代码注释掉#xff0c;终于通过SQL调试时#xff0c;弹出…最近在调试一个带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 isPRAGMA AUTONOMOUS_TRANSACTION;begininsert into Msg values(AutoNomouse Insert);commit;end;非自治事务CREATE OR REPLACE Procedure NonAutoNomouse_Insert asbegininsert into Msg Values(NonAutonomouse Insert);commit;end;SQL begin2 3 insert into Msg Values(This Main Info);4 5 NonAutoNomouse_Insert;6 7 rollback;8 9 end10 ;11 /PL/SQL procedure successfully completedSQL select * from msg;MSG--------------------------------------------------This Main InfoNonAutonomouse Insert因为过程中有COMMIT;所以匿名块中得RULLBACK 是不起作用的 由此得出非自治事务中的COMMIT,ROLLBACK是会影响整个事务的。下面我们看一个另外一种情况SQL delete msg;2 rows deletedSQL这里没有COMMIT;SQL begin2 3 insert into Msg Values(This Main Info);4 5 rollback; --这里加了ROLLBACK;6 7 NonAutoNomouse_Insert;8 9 rollback;10 11 end12 ;13 /PL/SQL procedure successfully completedSQL select * from msg;MSG--------------------------------------------------This Main InfoNonAutonomouse InsertNonAutonomouse Insert竟然没有ROLLBACK (DELETE * FROM SSG ;) 为什么了因为过程就是一个新的SESSION所以前面的SESSION被正常EXIT,同时被自动提交 所以我们会看到三行数据。SQL commit;Commit completeSQL select * from msg;MSG--------------------------------------------------This Main InfoNonAutonomouse InsertNonAutonomouse InsertSQL commit;Commit completeSQL select * from msg;MSG--------------------------------------------------This Main InfoNonAutonomouse InsertNonAutonomouse Insert因为这里一个新的SESSION 所以是没有意义的事务控制语句。SQL delete msg;3 rows deletedSQL commit;Commit completeSQL select * from msg;MSG--------------------------------------------------可以看到这里是正常的提交下面看一下自制事务SQL begin2 3 insert into Msg Values(This Main Info);4 5 AutoNomouse_Insert;6 7 rollback;8 9 end10 11 ;12 /PL/SQL procedure successfully completedSQL 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.htmlhttp://blog.csdn.net/gigiouter/article/details/7616627