oracle 11g PL/SQL Programming学习十

----------------------------------------------------------------------------
-----------------PL/SQL学习笔记系列 By Cryking-----------------
------------------------转载请注明出处,谢谢!------------------------ 

 


在NDS中使用PL/SQL块来完成更新CLOB字段,注意USING子句中的参数传递模式应与存储过程传递参数的模式一致.

00:22:39 SCOTT@orcl> --建立PL/SQL存储过程,更新CLOB字段为空
00:41:02 SCOTT@orcl> CREATE OR REPLACE PROCEDURE get_clob(item_title_in VARCHAR2,
00:41:02   2                                       item_desc_out IN OUT CLOB) IS
00:41:02   3  BEGIN
00:41:02   4    UPDATE item
00:41:02   5       SET item_desc = empty_clob()
00:41:02   6     WHERE item_title = item_title_in
00:41:02   7    RETURNING item_desc INTO item_desc_out;
00:41:02   8  END get_clob;
00:41:03   9  /


Procedure created.


Elapsed: 00:00:00.27
00:41:05 SCOTT@orcl> DECLARE
00:42:50   2    -- Define explicit record structure.
00:42:50   3    target CLOB;
00:42:50   4    source VARCHAR2(2000) := 'CryKing!';
00:42:50   5    movie  VARCHAR2(60) := 'TEST_TITLE';
00:42:50   6    stmt   VARCHAR2(2000);
00:42:50   7  BEGIN
00:42:50   8    -- Set statement
00:42:50   9    stmt := 'BEGIN ' || ' get_clob(:input,:output); ' || 'END;';
00:42:50  10    EXECUTE IMMEDIATE stmt
00:42:50  11      USING movie, IN OUT target;
00:42:50  12    dbms_lob.writeappend(target, LENGTH(source), source);
00:42:50  13  END;
00:42:51  14  /


PL/SQL procedure successfully completed.


Elapsed: 00:00:00.02
00:42:53 SCOTT@orcl> select * from item;


   ITEM_ID ITEM_TITLE ITEM_DESC
---------- ---------- ------------------
         1 TEST_TITLE CryKing!


1 row selected.


Elapsed: 00:00:00.01




你不能在执行动态PL/SQL块时使用RETURING INTO子句,因为RETURING INTO子句只能在有INSERT,UPDATE,DELETE语句时使用.


不定个数的输入参数的动态语句
此时需要使用DBMS_SQL包
示例:
11:29:29 SCOTT@orcl> create table emp_bak as select * from emp;


表已创建。


已用时间:  00: 00: 02.39
11:38:39 SCOTT@orcl> DECLARE
11:38:40   2    -- Declare explicit record structure and table of structure.
11:38:40   3    TYPE emp_record IS RECORD(
11:38:40   4       empno VARCHAR2(60)
11:38:40   5      ,ename VARCHAR2(60));
11:38:40   6    TYPE emp_table IS TABLE OF emp_record;
11:38:40   7    -- Declare dynamic variables.
11:38:40   8    emp_cursor SYS_REFCURSOR;
11:38:40   9    emp_rows   emp_table;
11:38:40  10    -- Declare DBMS_SQL variables.
11:38:40  11    c    INTEGER := dbms_sql.open_cursor;
11:38:40  12    fdbk INTEGER;
11:38:40  13    -- Declare local variables.
11:38:40  14    counter      NUMBER := 1;
11:38:40  15    column_names DBMS_SQL.VARCHAR2_TABLE;
11:38:40  16    emp_nos      DBMS_SQL.NUMBER_TABLE;
11:38:40  17    stmt         VARCHAR2(2000);
11:38:40  18    substmt      VARCHAR2(2000) := '';
11:38:40  19  BEGIN
11:38:40  20    -- Find the rows that meet the criteria.
11:38:40  21    FOR i IN (SELECT 'emp_nos' AS column_names
11:38:40  22                    ,empno
11:38:40  23                FROM emp_bak
11:38:40  24               WHERE REGEXP_LIKE(ename, '^S'))
11:38:40  25    LOOP
11:38:40  26      column_names(counter) := counter;
11:38:40  27      emp_nos(counter) := i.empno;
11:38:40  28      counter := counter + 1;
11:38:40  29    END LOOP;
11:38:40  30    -- Dynamically create substatement.
11:38:40  31    IF emp_nos.COUNT = 1 THEN
11:38:40  32      substmt := 'WHERE empno IN (:emp_nos)';
11:38:40  33    ELSE
11:38:40  34      substmt := 'WHERE empno IN (';
11:38:40  35      FOR i IN 1 .. emp_nos.COUNT
11:38:40  36      LOOP
11:38:40  37        IF i = 1 THEN
11:38:40  38          substmt := substmt || ':' || i;
11:38:40  39        ELSE
11:38:40  40          substmt := substmt || ',:' || i;
11:38:40  41        END IF;
11:38:40  42      END LOOP;
11:38:40  43      substmt := substmt || ')';
11:38:40  44    END IF;
11:38:40  45    -- Set statement.
11:38:40  46    stmt := 'SELECT empno, ename ' || 'FROM emp_bak ' || substmt;
11:38:40  47    --输出查看
11:38:40  48    dbms_output.put_line('stmt:' || stmt);
11:38:40  49    -- Parse the statement with DBMS_SQL.
11:38:40  50    dbms_sql.parse(c, stmt, dbms_sql.native);
11:38:40  51    -- Bind the bind variable name and value.
11:38:40  52    FOR i IN 1 .. emp_nos.COUNT
11:38:40  53    LOOP
11:38:40  54      dbms_sql.bind_variable(c, column_names(i), emp_nos(i));
11:38:40  55    END LOOP;
11:38:40  56    -- Execute using DBMS_SQL.
11:38:40  57    fdbk := dbms_sql.execute(c);
11:38:40  58    -- Convert the cursor to NDS.
11:38:40  59    emp_cursor := dbms_sql.to_refcursor(c);
11:38:40  60    -- Open and read dynamic cursor, then close it.
11:38:40  61    FETCH emp_cursor BULK COLLECT
11:38:40  62      INTO emp_rows;
11:38:40  63    FOR i IN 1 .. emp_rows.COUNT
11:38:40  64    LOOP
11:38:40  65      dbms_output.put_line('[' || emp_rows(i).empno || '][' || emp_rows(i)
11:38:40  66                           .ename || ']');
11:38:40  67    END LOOP;
11:38:40  68    -- Close the System Reference Cursor.
11:38:40  69    CLOSE emp_cursor;
11:38:40  70  END;
11:38:40  71  /
stmt:SELECT empno, ename FROM emp_bak WHERE empno IN (:1,:2)
[7369][SMITH]
[7788][SCOTT]


PL/SQL 过程已成功完成。


已用时间:  00: 00: 00.01



上面的示例动态的构建了一个sql语句(SELECT empno, ename FROM emp_bak WHERE empno IN (:1,:2)).
使用循环来绑定所有的绑定变量(:1,:2,:3...)到emp_nos关联数组(emp_nos存放的是满足查询条件的主键empno).
还使用了DBMS_SQL.TO_REFCURSOR函数将标准的DBMS_SQL游标转换为弱类型的系统游标.这里会自动关闭DBMS_SQL游标.如果
你在DBMS_SQL.TO_REFCURSOR之后再执行DBMS_SQL.close_cursor你将会获得错误ORA-29471.




DBMS_SQL包
oracle公司从oracle 7开始引进DBMS_SQL包.它提供了一种方法来存储用来动态构建SQL语句的对象代码.
在DBMS_SQL之前,你不能存储SQL语句,除非存在相同定义的表.
在8i的时候,DBMS_SQL开始支持集合类型.
DBMS_SQL仍有一个主要的特性是NDS没有的.那就是当返回字段的数据类型及数量未知时它能动态管理语句.
它由两个存储来完成:DESCRIBE_COLUMNS和DESCRIBE_COLUMNS2.
像NDS一样,DBMS_SQL也支持字符串的拼接和绑定变量.
DBMS_SQL包是SYS模式拥有的.有时有必要先给SYSTEM用户赋予权限.然后你可以给单独的用户再赋予使用权限.
如:
00:31:33 SYS@ORCL> GRANT EXECUTE ON dbms_sql TO system WITH GRANT OPTION;


Grant succeeded.


Elapsed: 00:00:00.08



使用DBMS_SQL包来执行动态的DDL语句
--注意本例运行在SQL*PLUS下,并使用了替换变量
00:41:21 SCOTT@orcl> DECLARE
00:41:48   2    -- Define local DBMS_SQL variables, and open cursor.
00:41:48   3    c    INTEGER := dbms_sql.open_cursor;
00:41:48   4    fdbk INTEGER;
00:41:48   5    stmt VARCHAR2(2000);
00:41:48   6  BEGIN
00:41:48   7    -- Use a loop to check whether to drop a sequence.
00:41:48   8    FOR i IN (SELECT null
00:41:48   9                FROM user_objects
00:41:48  10               WHERE object_name = '&&1') LOOP
00:41:48  11      -- Build, parse, and execute SQL statement, then close cursor.
00:41:48  12      stmt := 'DROP TABLE &&1';
00:41:48  13      dbms_sql.parse(c, stmt, DBMS_SQL.NATIVE);
00:41:48  14      fdbk := dbms_sql.execute(c);
00:41:48  15      dbms_sql.close_cursor(c);
00:41:48  16      dbms_output.put_line('Dropped TABLE [&&1].');
00:41:48  17    END LOOP;
00:41:48  18  END;
00:41:48  19  /
Enter value for 1: NOTEXISTS_TAB


PL/SQL procedure successfully completed.


Elapsed: 00:00:00.07
00:46:20 SCOTT@orcl> UNDEFINE 1
00:46:23 SCOTT@orcl> /
Enter value for 1: EMP_BAK
Dropped TABLE [EMP_BAK].


PL/SQL procedure successfully completed.


Elapsed: 00:00:00.27




使用DBMS_SQL包来执行动态的DML语句
动态的DML语句经常作为字符串在运行时创建.
示例:
--注意dbms_application_info包的使用
01:02:36 SCOTT@orcl> EXEC dbms_application_info.set_client_info('CRY');


PL/SQL procedure successfully completed.


Elapsed: 00:00:00.06
01:03:54 SCOTT@orcl> DECLARE
01:05:12   2    -- Define local DBMS_SQL variables, and open cursor.
01:05:12   3    c     INTEGER := dbms_sql.open_cursor;
01:05:12   4    fdbk  INTEGER;
01:05:12   5    stmt1 VARCHAR2(2000);
01:05:12   6    stmt2 VARCHAR2(20) := '-1'')';
01:05:12   7    -- V$SESSION.CLIENT_INFO variable.
01:05:12   8    client VARCHAR2(64);
01:05:12   9  BEGIN
01:05:12  10    stmt1 := 'INSERT INTO EMP_BAK(EMPNO,ENAME) VALUES ' || '( 123,''TEST_';
01:05:12  11    -- Get the current CLIENT_INFO value and conditionally append to string.
01:05:12  12    dbms_application_info.read_client_info(client);
01:05:12  13    IF client IS NOT NULL THEN
01:05:12  14      stmt1 := stmt1 || client || ''')';
01:05:12  15    ELSE
01:05:12  16      stmt1 := stmt1 || stmt2;
01:05:12  17    END IF;
01:05:12  18    DBMS_OUTPUT.put_line('stmt1:'||stmt1);
01:05:12  19    -- Build, parse, and execute SQL statement, then close cursor.
01:05:12  20    dbms_sql.parse(c, stmt1, dbms_sql.native);
01:05:12  21    fdbk := dbms_sql.execute(c);
01:05:12  22    dbms_sql.close_cursor(c);
01:05:12  23    dbms_output.put_line('Rows Inserted [' || fdbk || ']');
01:05:12  24  END;
01:05:13  25  /
stmt1:INSERT INTO EMP_BAK(EMPNO,ENAME) VALUES ( 123,'TEST_CRY')
Rows Inserted [1]


PL/SQL procedure successfully completed.


Elapsed: 00:00:00.02



使用BIND_VARIABLE来绑定标量,使用BIND_ARRAY来绑定嵌套表.
你也可以使用DBMS_SQL来执行PL/SQL块.

示例:

--使用DBMS_SQL来绑定变量
01:05:14 SCOTT@orcl> CREATE OR REPLACE PROCEDURE insert_empbak(empno  number,
01:19:03   2                                            ename  VARCHAR2,
01:19:03   3                                            deptno number := NULL) IS
01:19:03   4    -- Define local DBMS_SQL variables.
01:19:03   5    c    INTEGER := dbms_sql.open_cursor;
01:19:03   6    fdbk INTEGER;
01:19:03   7    stmt VARCHAR2(2000);
01:19:03   8    -- Variable to get OUT parameter value.
01:19:03   9    client VARCHAR2(64);
01:19:03  10  BEGIN
01:19:03  11    stmt := 'INSERT INTO emp_bak(empno,ename,deptno) VALUES ( :empno,:ename,:deptno)';
01:19:03  12    -- Call and dynamically set the session for the CLIENT_INFO value.
01:19:03  13    dbms_application_info.read_client_info(client);
01:19:03  14    IF client IS NOT NULL THEN
01:19:03  15      client := client;
01:19:03  16    ELSE
01:19:03  17      client := '-1';
01:19:03  18    END IF;
01:19:03  19    -- Parse and execute the statement.
01:19:03  20    dbms_sql.parse(c, stmt, dbms_sql.native);
01:19:03  21    dbms_sql.bind_variable(c, 'empno', empno);
01:19:03  22    dbms_sql.bind_variable(c, 'ename', ename || client);
01:19:03  23    dbms_sql.bind_variable(c, 'deptno', deptno);
01:19:03  24    fdbk := dbms_sql.execute(c);
01:19:03  25    dbms_sql.close_cursor(c);
01:19:03  26    dbms_output.put_line('Rows Inserted [' || fdbk || ']');
01:19:03  27  END insert_empbak;
01:19:04  28  /


Procedure created.


Elapsed: 00:00:00.30
01:20:07 SCOTT@orcl> BEGIN INSERT_EMPBAK(321,'KING_',33); END;
01:20:21   2  /
Rows Inserted [1]


PL/SQL procedure successfully completed.


Elapsed: 00:00:00.04
01:20:40 SCOTT@orcl> SELECT EMPNO,ENAME,DEPTNO FROM EMP_BAK WHERE DEPTNO=33;


     EMPNO ENAME          DEPTNO
---------- ---------- ----------
       321 KING_CRY           33


1 row selected.


Elapsed: 00:00:00.00

你应当注意在上面动态的DML语句中,已经没有单引号来界定传入的字符值了.
这是因为值和数据类型已经绑定到语句了.


--使用DBMS_SQL包处理返回一行数据的动态SELECT语句
01:46:08 SCOTT@orcl> DECLARE
01:50:49   2    c         INTEGER := dbms_sql.open_cursor;
01:50:49   3    fdbk      INTEGER;
01:50:49   4    statement VARCHAR2(2000);
01:50:49   5    v_s       VARCHAR2(1) := 'S';
01:50:49   6    v_ename   VARCHAR2(60);
01:50:49   7    v_empno   number(4);
01:50:49   8  BEGIN
01:50:49   9    -- Build and parse SQL statement.
01:50:49  10    statement := 'SELECT empno, ename ' ||
01:50:49  11                 'FROM emp_bak WHERE substr(ename,0,1) = :s AND ROWNUM=1';
01:50:49  12    dbms_output.put_line('statement:'||statement);
01:50:49  13    dbms_sql.parse(c, statement, dbms_sql.native);
01:50:49  14    -- Define column mapping, execute statement, and copy results.
01:50:49  15    dbms_sql.define_column(c, 1, v_empno); -- Define OUT mode variable.
01:50:49  16    dbms_sql.define_column(c, 2, v_ename, 60); -- Define OUT mode variable.
01:50:49  17    dbms_sql.bind_variable(c, 's', v_s); -- Bind IN mode variable.
01:50:49  18    fdbk := dbms_sql.execute_and_fetch(c);
01:50:49  19    dbms_sql.column_value(c, 1, v_empno); -- Copy query column to variable.
01:50:49  20    dbms_sql.column_value(c, 2, v_ename); -- Copy query column to variable.
01:50:49  21    -- Print return value and close cursor.
01:50:49  22    dbms_output.put_line('[' || v_empno || '][' || NVL(v_ename, 'None') || ']');
01:50:49  23    dbms_sql.close_cursor(c);
01:50:49  24  END;
01:50:50  25  /
statement:SELECT empno, ename FROM emp_bak WHERE substr(ename,0,1) = :s AND ROWNUM=1
[7369][SMITH]


PL/SQL procedure successfully completed.


Elapsed: 00:00:00.06



--使用DBMS_SQL包处理返回多行数据的动态SELECT语句
01:50:51 SCOTT@orcl> DECLARE
01:53:54   2    c         INTEGER := dbms_sql.open_cursor;
01:53:54   3    fdbk      INTEGER;
01:53:54   4    statement VARCHAR2(2000);
01:53:54   5    v_s       VARCHAR2(1) := 'A';
01:53:54   6    v_ename   VARCHAR2(60);
01:53:54   7    v_empno   number(4);
01:53:54   8  BEGIN
01:53:54   9    -- Build and parse SQL statement.
01:53:54  10    statement := 'SELECT empno, ename ' ||
01:53:54  11                 'FROM emp_bak WHERE substr(ename,0,1) = :s ';
01:53:54  12    dbms_output.put_line('statement:'||statement);
01:53:54  13    dbms_sql.parse(c, statement, dbms_sql.native);
01:53:54  14    -- Define column mapping, execute statement, and copy results.
01:53:54  15    dbms_sql.define_column(c, 1, v_empno); -- Define OUT mode variable.
01:53:54  16    dbms_sql.define_column(c, 2, v_ename, 60); -- Define OUT mode variable.
01:53:54  17    dbms_sql.bind_variable(c, 's', v_s); -- Bind IN mode variable.
01:53:54  18    fdbk := dbms_sql.execute(c);
01:53:54  19    LOOP
01:53:54  20      EXIT WHEN dbms_sql.fetch_rows(c) = 0;
01:53:54  21    dbms_sql.column_value(c, 1, v_empno); -- Copy query column to variable.
01:53:54  22    dbms_sql.column_value(c, 2, v_ename); -- Copy query column to variable.
01:53:54  23    -- Print return value and close cursor.
01:53:54  24    dbms_output.put_line('[' || v_empno || '][' || NVL(v_ename, 'None') || ']');
01:53:54  25    END LOOP;
01:53:54  26    dbms_sql.close_cursor(c);
01:53:54  27  END;
01:53:55  28  /
statement:SELECT empno, ename FROM emp_bak WHERE substr(ename,0,1) = :s
[7499][ALLEN]
[7876][ADAMS]


PL/SQL procedure successfully completed.

作者:Steven Feuerstein, Bill Pribyl 出版日期:October 1, 2009 出版社:O'Reilly 页数:1226 ISBN:ISBN-10: 0596514468 ISBN-13: 978-0596514464 文件格式:PDF 文件大小:15.06 MB Review If you’re doing database application development in the Oracle environment, you’re going to have to know PL/SQL, the company’s extended query and update language. If you want your programs to exploit the special capabilities of Oracle software, you’ll need to know the language well. That’s where the third edition of Oracle PL/SQL Programming comes into play. It’s an absolutely comprehensive reference (as well as a rather extensive tutorial) on PL/SQL, ideally suited to answering your questions about how to perform some programming tasks and reminding you of the characteristics of functions, triggers, and other elements of the database programmer’s toolkit. The new edition covers calls to Java methods from within PL/SQL programs, autonomous transactions, object type inheritance, and the new Timestamp and XMLType data types. There’s also more information about server internals–the way PL/SQL programs are run–than before, better enabling readers to optimize their code for fast and safe execution. Steven Feuerstein takes care to explain, with prose and example code, the characteristics of PL/SQL elements. In explaining number conversions, for example, he explores Oracle’s different ways of formatting numbers, then details the behavior of the to_number function under different conditions (with and without a specified format model, and with National Language Support information attached). It’s a helpful approach that will have readers using the index to locate places in which Feuerstein mentions language elements of interest. –David Wall Topics covered: How to use Oracle PL/SQL in all its manifestations through Oracle9i. Fundamentals of program structure (loops, cases, exceptions, etc.) and execution get attention, as do data types, transaction management, triggers, and the object-oriented aspects of the language. There’s also coverage of calls to external Java and C programs. –This text refers to the Paperback edition. Product Description This book is the definitive reference on PL/SQL, considered throughout the database community to be the best Oracle programming book available. Like its predecessors, this fifth edition of Oracle PL/SQL Programming covers language fundamentals, advanced coding techniques, and best practices for using Oracle’s powerful procedural language. Thoroughly updated for Oracle Database 11g Release 2, this edition reveals new PL/SQL features and provides extensive code samples, ranging from simple examples to complex and complete applications, in the book and on the companion website. This indispensable reference for both novices and experienced Oracle programmers will help you: Get PL/SQL programs up and running quickly, with clear instructions for executing, tracing, testing, debugging, and managing PL/SQL code Optimize PL/SQL performance with the aid of a brand-new chapter in the fifth edition Explore datatypes, conditional and sequential control statements, loops, exception handling, security features, globalization and localization issues, and the PL/SQL architecture Understand and use new Oracle Database 11g features, including the edition-based redefinition capability, the function result cache, the new CONTINUE statement, fine-grained dependency tracking, sequences in PL/SQL expressions, supertype invocation from subtypes, and enhancements to native compilation, triggers, and dynamic SQL Use new Oracle Database 11g tools and techniques such as PL/Scope, the PL/SQL hierarchical profiler, and the SecureFiles technology for large objects Build modular PL/SQL applications using procedures, functions, triggers, and packages
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值