PL/SQL 批量操作
2015-04-19 22:32
113 查看
-- Start
在 PL/SQL 中执行 SQL 语句的时候,PL/SQL 引擎将参数传递给 SQL 引擎,然后接收返回值。通常是传递一个参数,接收一个返回值,如果有很多这样的操作,我们不得不把它放到一个循环语句中,如下是一个简单的例子。
那有没有一种办法批量传递参数和批量接收返回值呢?答案是肯定的,下面是一个简单的例子。
理想很丰满,现实很骨感,如果在批量执行的过程中出异常了,Oracle 该如何处理?Oracle 会中断执行,回滚所有操作。如果我们想让它中断执行,提交已经做的更改,该怎么办呢?看看下面的例子吧。
如果我们想让它忽略异常继续执行,该怎么做呢?看看下面的例子吧。
下面我们看一个如何批量接收返回值的例子。
下面的例子将返回值放到一个记录中。
下面的例子游标中批量接收返回值
下面的例子从删除语句中获取返回值。
--更多参见:Oracle PL/SQL 精萃
-- 声明:转载请注明出处
-- Last Edited on 2015-06-30
-- Created by ShangBo on 2015-04-19
-- End
在 PL/SQL 中执行 SQL 语句的时候,PL/SQL 引擎将参数传递给 SQL 引擎,然后接收返回值。通常是传递一个参数,接收一个返回值,如果有很多这样的操作,我们不得不把它放到一个循环语句中,如下是一个简单的例子。
DECLARE TYPE NumList IS VARRAY(20) OF NUMBER; emps NumList := NumList(10, 30, 70); BEGIN FOR i IN emps.FIRST..emps.LAST LOOP DELETE FROM employees WHERE employee_id = emps(i); END LOOP; END;
那有没有一种办法批量传递参数和批量接收返回值呢?答案是肯定的,下面是一个简单的例子。
DECLARE TYPE NumList IS VARRAY(20) OF NUMBER; emps NumList := NumList(10, 30, 70); BEGIN -- FORALL 语句批量执行下面的语句 FORALL i IN emps.FIRST..emps.LAST DELETE FROM employees WHERE employee_id = emps(i); END;
理想很丰满,现实很骨感,如果在批量执行的过程中出异常了,Oracle 该如何处理?Oracle 会中断执行,回滚所有操作。如果我们想让它中断执行,提交已经做的更改,该怎么办呢?看看下面的例子吧。
DECLARE TYPE NumList IS VARRAY(20) OF NUMBER; emps NumList := NumList(10, 30, 70); BEGIN FORALL i IN emps.FIRST..emps.LAST update employees set last_name = last_name || 'value too large exception' WHERE employee_id = emps(i); EXCEPTION WHEN OTHERS THEN COMMIT; END;
如果我们想让它忽略异常继续执行,该怎么做呢?看看下面的例子吧。
DECLARE TYPE NumList IS VARRAY(20) OF NUMBER; emps NumList := NumList(10, 30, 70); -- 批量操作失败后会抛出 24381 错误 bulk_errors EXCEPTION; PRAGMA EXCEPTION_INIT(bulk_errors, -24381); BEGIN -- S***E EXCEPTIONS 表示保存异常继续执行 FORALL i IN emps.FIRST..emps.LAST S***E EXCEPTIONS update employees set last_name = last_name || 'Values too long' WHERE employee_id = emps(i); EXCEPTION WHEN bulk_errors THEN -- SQL%BULK_EXCEPTIONS.COUNT 表示发生错误的条数 FOR i IN 1..SQL%BULK_EXCEPTIONS.COUNT LOOP DBMS_OUTPUT.PUT_LINE ('执行第' || SQL%BULK_EXCEPTIONS(i).ERROR_INDEX || '条语句发生了错误,错误代码:' || SQL%BULK_EXCEPTIONS(i).ERROR_CODE || ', 错误信息:' || SQLERRM(-(SQL%BULK_EXCEPTIONS(i).ERROR_CODE))); END LOOP; COMMIT; WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('未知异常.'); ROLLBACK; RAISE; -- 显示删除结果 FOR i IN emps.FIRST..emps.LAST LOOP DBMS_OUTPUT.PUT_LINE ('第' || i || '条语句更新了' || SQL%BULK_ROWCOUNT(i) || '行'); END LOOP; DBMS_OUTPUT.PUT_LINE ('总共更新了' || SQL%ROWCOUNT || '行'); END;
下面我们看一个如何批量接收返回值的例子。
DECLARE TYPE ID_TABLE IS TABLE OF EMPLOYEES.EMPLOYEE_ID%TYPE; TYPE NAME_TABLE IS TABLE OF EMPLOYEES.LAST_NAME%TYPE; ids ID_TABLE; names NAME_TABLE; BEGIN SELECT EMPLOYEE_ID, LAST_NAME BULK COLLECT INTO ids, names -- 批量返回数据 FROM EMPLOYEES ORDER BY EMPLOYEE_ID; FOR i IN ids.FIRST()..names.LAST() LOOP DBMS_OUTPUT.PUT_LINE('EMPLOYEE #' || ids(i) || ': ' || names(i)); END LOOP; END;
下面的例子将返回值放到一个记录中。
DECLARE CURSOR c1 IS SELECT EMPLOYEE_ID, LAST_NAME FROM EMPLOYEES; TYPE ID_NAME_TABLE IS TABLE OF c1%ROWTYPE; emps ID_NAME_TABLE; BEGIN SELECT EMPLOYEE_ID, LAST_NAME BULK COLLECT INTO emps -- 批量返回数据 FROM EMPLOYEES ORDER BY EMPLOYEE_ID; FOR i IN emps.FIRST()..emps.LAST() LOOP DBMS_OUTPUT.PUT_LINE('EMPLOYEE #' || emps(i).EMPLOYEE_ID || ':' || emps(i).LAST_NAME); END LOOP; END;
下面的例子游标中批量接收返回值
DECLARE CURSOR c1 IS SELECT EMPLOYEE_ID, LAST_NAME FROM EMPLOYEES; TYPE ID_NAME_TABLE IS TABLE OF c1%ROWTYPE; emps ID_NAME_TABLE; BEGIN OPEN c1; LOOP -- 每次取10条 FETCH c1 BULK COLLECT INTO emps LIMIT 10; FOR i IN emps.FIRST()..emps.LAST() LOOP DBMS_OUTPUT.PUT_LINE('EMPLOYEE #' || emps(i).EMPLOYEE_ID || ':' || emps(i).LAST_NAME); END LOOP; EXIT WHEN c1%NOTFOUND; END LOOP; CLOSE c1; END;
下面的例子从删除语句中获取返回值。
DECLARE CURSOR c1 IS SELECT EMPLOYEE_ID, LAST_NAME FROM EMPLOYEES; TYPE ID_NAME_TABLE IS TABLE OF c1%ROWTYPE; emps ID_NAME_TABLE; BEGIN DELETE FROM EMPLOYEES RETURNING EMPLOYEE_ID, LAST_NAME BULK COLLECT INTO emps; -- 批量返回数据 FOR i IN emps.FIRST()..emps.LAST() LOOP DBMS_OUTPUT.PUT_LINE('EMPLOYEE #' || emps(i).EMPLOYEE_ID || ':' || emps(i).LAST_NAME); END LOOP; END;
--更多参见:Oracle PL/SQL 精萃
-- 声明:转载请注明出处
-- Last Edited on 2015-06-30
-- Created by ShangBo on 2015-04-19
-- End
相关文章推荐
- PL/SQL 创建、查看、操作用户
- Oracle PL\SQL操作(六)用户和角色
- Oracle基本操作八:PL/SQL特殊数据类型%type %rowtype VARRAY TABLE RECORD
- LINQ To SQL在N层应用程序中的CUD操作、批量删除、批量更新
- Oracle在pl/sql中操作基本表 记录
- 批量复制操作(SqlBulkCopy)的出错处理:事务提交、回滚
- Oracle PL/SQL操作(四)索引与约束
- sql 批量操作数据
- 批量SQL操作之批量获取
- C#利用SqlDataAdapte对DataTable进行批量数据操作
- oracle数据库操作——SQL Plus和PL/SQL
- PL/SQL操作Excel
- java批量操作sql替换数据库数据
- Oracle PL/SQL操作(五)
- PL/SQL 批量SQL
- sqlmap动态sql优化,避免传参失误批量修改和删除操作!
- 批量操作SQL数据,遇到表中建有触发器时,临时停止触发器。
- 解决pl/sql devloper 中数据库操作语句中文乱码的问题
- Oracle PL/SQL操作(六)用户和角色