函式中的DML語句的執行問題--自治事務
問題:寫一個函式,函式中要更新資料庫中的某個欄位,函式在使用時格式是:select funcName() from dual; 那麼此函式中如果含有update語句
函式:
create or replace function CalABGrpRearBounty()
return number is Result number;
begin
update larearrelation set rearcommflag = 2 where rearcommflag = 1;
commit;
end;
報:ORA-14551,不能在查詢語句中執行dml語句
開始以為函式本身有問題,其實不然,是因為select funcName() from dual; 這個語句的問題
解決:函式中使用自治事務。
自治事務實現的功能是自治事務的提交或回滾不影響當前的事務。同時自治事務也是看不到當前會話所做的未提交的修改的。
create or replace function CalABGrpRearBounty(tAgentCode laagent.agentcode%type,
tAgentGrade latree.agentgrade%type
)
return number is pragma autonomous_transaction
mResult number;
mAgentCode laagent.agentcode%type;
mFYCMin lawageradix.fycmin%type; -- 非本人推薦的獎金數量
mFYCMax lawageradix.fycmax%type; -- 本人推薦的獎金數量
mRecommendCount number; -- 推薦次數
mRearCommFlag number;
begin
mResult := 0;
-- 查詢育成獎金標準
select FYCMin into mFYCMin from lawageradix where agentgrade = tAgentGrade and wagecode = 'WA0009' and branchtype = 2;
if(mFYCMin is not null and mFYCMin > 0)
then
begin
select FYCMax into mFYCMax from lawageradix where agentgrade = tAgentGrade and wagecode = 'WA0009' and branchtype = 2;
-- 查詢被育成人,存在育成關係,且未提傭,且計算日期在育成止期後
-- rearcommflag=1:未進行佣金計算;rearcommflag=2:已進行過佣金計算;rearcommflag=3:已稽核。
declare cursor rearListCursor is
select agentcode from larearrelation where rearagentcode = tAgentCode and rearflag = 1 and (rearcommflag = 1 or rearcommflag = 2);
begin
open rearListCursor;
loop
fetch rearListCursor into mAgentCode;
exit when rearListCursor%notfound;
-- 查詢育成人是否推薦人
select count(*) into mRecommendCount from larecomrelation where agentcode = mAgentCode and recomagentcode = tAgentCode
and recomflag = 1;
if(mRecommendCount = 1)
then
mResult := mResult + mFYCMax;
else
mResult := mResult + mFYCMin;
end if;
-- 更新rearcommflag=2,表示已計算過佣金
select rearcommflag into mRearCommFlag from larearrelation where rearagentcode = tAgentCode and agentcode = mAgentCode and rearflag = 1;
if(mRearCommFlag = 1)
then
begin
update larearrelation set rearcommflag = 2 where rearcommflag = 1 and rearagentcode = tAgentCode and agentcode = mAgentCode and rearflag = 1 ;
commit;
end;
end if;
end loop;
close rearListCursor;
end;
end;
end if;
return(mResult);
end;
以下摘自:作者: 楊廷琨, 出處:blog, 責任編輯: 王曉晨, 2008-08-04 09:31
這兩天看了11g的CONCEPT文件的事務部分,發現自治事務還有一些以前沒有注意到的地方,這裡簡單總結一下。
這一篇簡單描述一下自治事務可以使用的位置。
自治事務可以使用在以下的位置:
儲存過程和函式;
本地過程和函式;
包;
物件方法;
匿名塊的最頂層。
其中過程、函式和包中使用自治事務很常見,大部分自治事務的情況都屬於這種情況。由於物件相對使用的比較少,所以物件方法中的自治事務也是比較少見的,不過由於物件中的方法和包中的儲存過程、函式十分相似,所以這種情況也是情理之中的。
剩下的兩種情況,是以前所不瞭解的。從來沒有想過對於本地過程和函式也是可以定義為自治事務的,不過本地過程定義為自治事務是十分方便的功能,使得過程中需要用到自治事務的功能時,不必再額外定義一個自治事務的儲存過程,只需要在當前的過程中定義一個自治的本地過程就可以了。
一個簡單的例子如下:
SQL> CREATE TABLE T_AUTO_TRANS (ID NUMBER, NAME VARCHAR2(30)); |
表已建立。
SQL> CREATE TABLE T_LOG (ID NUMBER, NAME VARCHAR2(30)); |
表已建立。
下面建立一個LOCAL PROCEDURE的自治事務的例子:
SQL> DECLARE 2 PRAGMA AUTONOMOUS_TRANSACTION; 3 BEGIN 4 INSERT INTO T_LOG VALUES (1, 'AUTONOMOUS_TRANSACTION'); 5 COMMIT; 6 END; 7 / |
PL/SQL 過程已成功完成。
SQL> SELECT * FROM T_AUTO_TRANS; ID NAME ---------- ------------------------------ 1 TEST SQL> SELECT * FROM T_LOG; ID NAME ---------- ------------------------------ 1 AUTONOMOUS_TRANSACTION 1 AUTONOMOUS_TRANSACTION SQL> ROLLBACK; |
回退已完成。
SQL> SELECT * FROM T_AUTO_TRANS; |
SQL> SELECT * FROM T_LOG; ID NAME ---------- ------------------------------ 1 AUTONOMOUS_TRANSACTION 1 AUTONOMOUS_TRANSACTION |
這種情況的意義沒有本地過程的大,不過對於編寫包含大量的SQL和PL/SQL的sql檔案還是有不少幫助的。
Oracle 11g自治事務更像是在單獨的會話中執行,它的事務狀態不會影響當前的事務,它也不會看到當前事務沒有提交的修改。
自治事務實現的功能是自治事務的提交或回滾不影響當前的事務。同時自治事務也是看不到當前會話所做的未提交的修改的。
SQL> TRUNCATE TABLE T_AUTO_TRANS; |
表被截斷。
SQL> CREATE OR REPLACE PROCEDURE P_TEST AS 2 BEGIN 3 INSERT INTO T_AUTO_TRANS VALUES (2, 'TEST'); 4 FOR I IN (SELECT COUNT(*) CNT FROM T_AUTO_TRANS) LOOP 5 DBMS_OUTPUT.PUT_LINE('P_TEST:' || I.CNT); 6 END LOOP; 7 END; 8 / |
過程已建立。
SQL> CREATE OR REPLACE PROCEDURE P_TEST_AUTO AS 2 PRAGMA AUTONOMOUS_TRANSACTION; 3 BEGIN 4 INSERT INTO T_AUTO_TRANS VALUES (2, 'TEST'); 5 FOR I IN (SELECT COUNT(*) CNT FROM T_AUTO_TRANS) LOOP 6 DBMS_OUTPUT.PUT_LINE('P_TEST_AUTO:' || I.CNT); 7 END LOOP; 8 COMMIT; 9 END; 10 / |
過程已建立。
SQL> INSERT INTO T_AUTO_TRANS VALUES (1, 'TEST'); |
已建立 1 行。
SQL> SET SERVEROUT ON SQL> EXEC P_TEST P_TEST:2 |
PL/SQL 過程已成功完成。
SQL> EXEC P_TEST_AUTO P_TEST_AUTO:1 |
可以看到,對於自治事務是看不到當前會話所作的未提交的修改的。
SQL> EXEC P_TEST P_TEST:4 |
PL/SQL 過程已成功完成。
而對於當前會話,由於自治事務的操作已經提交,因此之後的查詢是可以看到自治事務所進行的修改的。
自治事務看不到當前會話的修改,那麼自治事務呼叫的過程是否能看到自治事務的修改呢:
SQL> TRUNCATE TABLE T_AUTO_TRANS; |
表被截斷。
SQL> CREATE OR REPLACE PROCEDURE P_AUTO_TRANS AS 2 PRAGMA AUTONOMOUS_TRANSACTION; 3 BEGIN 4 INSERT INTO T_AUTO_TRANS VALUES (1, 'TEST'); 5 INSERT INTO T_AUTO_TRANS VALUES (2, 'TEST'); 6 FOR I IN (SELECT COUNT(*) CNT FROM T_AUTO_TRANS) LOOP 7 DBMS_OUTPUT.PUT_LINE('P_AUTO_TRANS:' || I.CNT); 8 END LOOP; 9 P_TEST; 10 P_TEST_AUTO; 11 COMMIT; 12 END; |
過程已建立。
SQL> INSERT INTO T_AUTO_TRANS VALUES (1, 'TEST'); |
已建立 1 行。
SQL> EXEC P_AUTO_TRANS P_AUTO_TRANS:2 P_TEST:3 P_TEST_AUTO:1 PL/SQL |
過程已成功完成。
建立一個自治事務,分別呼叫一個普通過程和一個聲明瞭自治事務的過程,結果可以看到,自治事務呼叫普通過程,可以看到自治事務所進行的修改,而對於自治事務呼叫的自治事務過程,是看不到自治事務所進行的修改的。
從這一點看,自治事務更像是在單獨的會話中執行,它的事務狀態不會影響當前的事務,它也不會看到當前事務沒有提交的修改。
總結:要想在SELECT語句中對錶進行修改,可以使用自治事務(Autonomous Transactions,AT)。自治事務(Autonomous Transactions)是由另外一個事務呼叫的,這個叫事務做主事務(Main Transaction,MT)。自治事務(Autonomous Transactions)的提交(commit)和回滾(rollback)並不影響主事務(MT)。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
相關推薦
ORACLE:SELECT語句裡呼叫函式使用DML語句進行UPDATE/INSERT/DELETE操作
需求: 公司一系統升級,要維護的資料庫表中已有資料,該表沒有序列、觸發器等。此表要直接插入一些資料,插入的資料為了和以前的資料相容(就是一樣)。該表主鍵的生成以前是在程式碼中分兩步進行的,即查詢、更新(現在要直接插入資料,不用服務端JAVA程式碼,不能用這個)。 做法: 本
Oracle中select語句執行過程
通過from子句中找到需要查詢的表 通過where子句進行非分組函式篩選判斷 通過group by子句完成分組操作 通過having字句完成組函式篩選判斷 通過select字句選擇顯示的列或表示式及組函式 通過order by字句進行排序操作
函式中的DML語句的執行問題--自治事務
問題:寫一個函式,函式中要更新資料庫中的某個欄位,函式在使用時格式是:select funcName() from dual; 那麼此函式中如果含有update語句 函式: create or replace function CalABGrpRearBounty() ret
laravel中查看執行的SQL語句
model http nec 條件 alt 今天 不能 conn obj 今天想查看laravel框架中執行的SQL語句,百度了一圈,才找到,這文檔真心看著不爽,下面上查看方法 DB::connection()->enableQueryLog();
oracle中for update語句執行時間過長的問題
oracle執行查詢語句SELECT s.sid, s.serial# FROM v$locked_object lo, dba_objects ao, v$session s WHERE ao.object_id = lo.object_id AND lo.session_id = s.sid 查出的兩個字
javascript中奇怪的執行結果(立即執行函式)
在下面的例子中,將IIFE賦值給一個變數message。message返回另外一個函式,該函式只是簡單地輸出變數x的值。有趣的事情是,當我們把變數x的初始值作為引數傳入函式時,可以在函式執行時所建立的閉包中捕獲變數x的值。無論在外部作用域中x的值發生了什麼變化,閉包將記住函式執行時變數x的值
java中try catch語句執行順序簡介
package com.string_lc; /** * @filename Test.java * @author l * @description */ public class Test { public static void main(String[] args) {
JS中的自執行函式
轉自:https://www.cnblogs.com/zuiyirenjian/p/3535126.html 在JS中,也常常需要複用,將一些常見的操作封裝起來,目前看到的很多JS庫,比如JQuery就是非常典型的,那麼如何在JS中寫一個可複用的呢?雖然在JS中有類的這個說法,但是我對這個玩意還
javascript中的立即執行函式(function(){…})()
javascript和其他程式語言相比比較隨意,所以javascript程式碼中充滿各種奇葩的寫法,有時霧裡看花,當然,能理解各型各色的寫法也是對javascript語言特性更進一步的深入理解。 ( function(){…} )()和( function (){…} () )是兩種javasc
使用mysqlbinlog從二進位制日誌檔案中查詢mysql執行過的sql語句
前提MySQL開啟了binlog日誌操作1. 檢視MySQL是否開啟binlog(進mysql操作) mysql> show variables like 'log_bin%'; 2. 查詢binlog檔名 &nbs
MyBatis學習總結(六)---使用log4j2將sql語句執行記錄輸出控制檯和檔案中
在上一篇部落格中我簡單的介紹了在MyBatis中如何使用日誌,並給出了一個在MyBatis中使用log4j的示例。 MyBatis中日誌的使用及使用log4j示例 下面介紹在MyBatis中如何使用log4j2將sql語句執行記錄輸出控制
伺服器無法繼續執行該事務,此會話中的活動事務已由另外一個會話提交或終止。
//執行事務處理 public void DoTran() { //建立連線並開啟 SqlConnection myConn=GetConn(); myConn.Open(); SqlCommand myComm=new SqlCo
ORACLE中查詢語句的執行順及where部分條件執行順序測試 Oracle中的一些查詢語句及其執行順序 Select 語句執行順序以及如何提高Oracle 基本查詢效率
Oracle中的一些查詢語句及其執行順序 原文地址:https://www.cnblogs.com/likeju/p/5039115.html 查詢條件:1)LIKE:模糊查詢,需要藉助兩個萬用字元,%:表示0到多個字元;_:標識單個字元。2)IN(list):用來取出符合列表範圍中的資料。3)NOT I
dljd_007_jdbc程式設計中的statement執行DML/DDL
一、使用statement的executeUpdate執行DML(增刪改)語句示例 package edu.aeon.jdbc; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManag
dljd_016_jdbc中使用PreparedStatement執行DQL(查詢)語句
一、jdbc使用preparedStatement執行dql(查詢)語句示例 package edu.aeon.jdbc.crud; import java.sql.Connection; import java.sql.PreparedStatement; import java.
dljd_015_使用PreparedStatement執行crud之DML語句(增加操作)
一、使用jdbc進行DML語句之增加資料操作示例 package edu.aeon.jdbc.crud; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException
關於java 中 switch 語句的執行順序
首先來一個正常的demo int i = 2; switch (i) { case 1: System.out.println("1"); break; case 2: System.out.println("2"); break;
習題 11.1 將例11.1的程式片斷補充和改寫成一個完整、正確的程式,用公用繼承方式。在程式中應包括輸入資料的函式,在程式執行時輸入num,name,sex,age,addr的值,程式應輸出以上。。
C++程式設計(第三版) 譚浩強 習題11.1 個人設計 習題 11.1 將例11.1的程式片斷補充和改寫成一個完整、正確的程式,用公用繼承方式。在程式中應包括輸入資料的函式,在程式執行時輸入num,n
dljd_027_增改刪在同一個事務中的預設執行順序
一、測試增刪改在同一個事務中的預設執行順序示例 package edu.aeon.test; import org.hibernate.Session; import org.hibernate.Transaction; import edu.aeon.aeonutils.GetSe
java中關於final,finally,finalize的區別?java中finally語句一定會執行嗎?
既然上一篇寫到繼承多型和封裝,那麼接著記一下final、finally和finalize的區別。最基礎的知識還是要鞏固牢靠的。 final:final作為java的修飾符,可以修飾類,變數和方法。被final修飾的類不能被繼承,修飾的變數不能更改值,修飾的方法不能被重寫。 finally:f