`

Oracle PL/SQL学习笔记

 
阅读更多
1 SQL*Plus环境
--------------------------------------
show all 显示所有SQL*Plus的命令名字
list or l 显示缓冲区的内容
list 4 显示当前SQL命令的第4行,并把第4行作为当前行。
change or c 用新的内容替换原来在一行中第一次出现内容,例如:SQL>c/(...)/('analyst')/
input or i 增加一行或多行
append or a 在一行后追加内容
del 删除当前行 删除SQL缓冲区中的当前行
run 显示并运行SQL缓冲区中的命令
/ 运行SQL缓冲区中的命令
edit 把SQL缓冲区中的命令写到操作系统下的文本文件,
并调用操作系统提供的编辑器执行修改。
set linesize 80 设置行的大小为80个字符宽度
set pagesize 100 设置页的大小为100行
ttitle 'smaple ttitle' 设置页头标
btitle 'smaple btitle' 设置页脚标
spool /home/zxin10/myresult.log 设置sqlplus的输出到文件中
spool off(out) 停止输出文件
column column_name format a18 wrap heading ’smaple-column-title’
格式化列输出,每列宽度18个字符,超过18个自动换行,列标题换成'column-title'
CLEAR COLUMNS 将所有列的显示属性设为缺省值.
2 异常exception
--------------------------------------
no_data_found
表示select没有查询到满足条件的数据行。
others
表示Oracle预定义错误范围之外的任何错误,Oracle用这个"others"捕捉所有 未知的错误。可以使用sqlcode函数,sqlerrm函数在错误处理模块中显示错误 代码和错误信息。而且,others处理必须是一个块的最后一个错误处理,否则, others处理的优先级比较高,权利比较大,它会捕捉所有错误,包括预定义的Oracle 错误和非预定义的Oracle错误。
too_many_rows
Oracle的隐式游标,一次只能检索一行数据,使用隐式游标时,异常处理机制如果检测 到游标返回的数据是多行数据,它就抛出too_many_rows类型的异常。
dup_val_on_index
在某个索引上,出现重复值。
value_error
在某个目标字段中,放入的数据长度或者数据范围,超出目标字段定义的长度或者范围 ,如,把'8613905180088'这个字符串插入userid字段中,而userid定义为varchar2(10), 就会出现这种异常。
Exception Raised when ...
ACCESS_INTO_NULL
Your program attempts to assign values to the attributes of an uninitialized
(atomically null) object.
CASE_NOT_FOUND
None of the choices in the WHEN clauses of a CASE statement is selected, and
there is no ELSE clause.
COLLECTION_IS_NULL
Your program attempts to apply collection methods other than EXISTS to an
uninitialized (atomically null) nested table or varray, or the program attempts
to assign values to the elements of an uninitialized nested table or varray.
CURSOR_ALREADY_OPEN
Your program attempts to open an already open cursor. A cursor must be closed
before it can be reopened. A cursor FOR loop automatically opens the cursor to
which it refers. So, your program cannot open that cursor inside the loop.
DUP_VAL_ON_INDEX
Your program attempts to store duplicate values in a database column that is
constrained by a unique index.
INVALID_CURSOR
Your program attempts an illegal cursor operation such as closing an unopened cursor.
INVALID_NUMBER
In a SQL statement, the conversion of a character string into a number fails
because the string does not represent a valid number. (In procedural statements,
VALUE_ERROR is raised.) This exception is also raised when the LIMIT-clause
expression in a bulk FETCH statement does not evaluate to a positive number.
LOGIN_DENIED
Your program attempts to log on to Oracle with an invalid username and/or password.
NO_DATA_FOUND
A SELECT INTO statement returns no rows, or your program references a deleted element
in a nested table or an uninitialized element in an index-by table. SQL aggregate
functions such as AVG and SUM always return a value or a null. So, a SELECT INTO
statement that calls an aggregate function never raises NO_DATA_FOUND. The FETCH
statement is expected to return no rows eventually, so when that happens, no
exception is raised.
NOT_LOGGED_ON
Your program issues a database call without being connected to Oracle.
PROGRAM_ERROR
PL/SQL has an internal problem.
ROWTYPE_MISMATCH
The host cursor variable and PL/SQL cursor variable involved in an assignment have
incompatible return types. For example, when an open host cursor variable is passed
to a stored subprogram, the return types of the actual and formal parameters must
be compatible.
SELF_IS_NULL
Your program attempts to call a MEMBER method on a null instance. That is, the
built-in parameter SELF (which is always the first parameter passed to a MEMBER
method) is null.
STORAGE_ERROR
PL/SQL runs out of memory or memory has been corrupted.
SUBs cript_BEYOND_COUNT
Your program references a nested table or varray element using an index number
larger than the number of elements in the collection.
SUBs cript_OUTSIDE_LIMIT
Your program references a nested table or varray element using an index number
(-1 for example) that is outside the legal range.
SYS_INVALID_ROWID
The conversion of a character string into a universal rowid fails because the
character string does not represent a valid rowid.
TIMEOUT_ON_RESOURCE
A time-out occurs while Oracle is waiting for a resource.
TOO_MANY_ROWS
A SELECT INTO statement returns more than one row.
VALUE_ERROR
An arithmetic, conversion, truncation, or size-constraint error occurs. For example,
when your program selects a column value into a character variable, if the value is
longer than the declared length of the variable, PL/SQL aborts the assignment and raises
VALUE_ERROR. In procedural statements, VALUE_ERROR is raised if the conversion of a
character string into a number fails. (In SQL statements, INVALID_NUMBER is raised.)
ZERO_DIVIDE
Your program attempts to divide a number by zero.
3 连接查询
----------------------------------------
假设两个表s1cardinf,s1prefer
s1cardinf内容:
allindex
1
2
3
s1prefer内容:
allindex
2
3
4
select a.allindex,b.allindex
from s1cardinf a , s1prefer b
where a.allindex = b.allindex ;
结果:
allindex,allindex
2 2
3 3
select a.allindex,b.allindex
from s1cardinf a , s1prefer b
where a.allindex (+) = b.allindex ;
结果:
allindex,allindex
2 2
3 3
null 4
select a.allindex,b.allindex
from s1cardinf a , s1prefer b
where a.allindex = b.allindex (+) ;
结果:
allindex,allindex
1 null
2 2
3 3
二.pl/sql 编程方面
1.自治事务:8i以上版本,不影响主事务。
在存储过程的is/as
后面声明PRAGMA AUTONOMOUS_TRANSACTION;
自治事务防止嵌套提交,使事务在自己的事务区内提交或回滚不会影响其他的事务。
2、包
包说明(package specification),包头,存放关于包的内容的信息,定义包的用户可见的过程、
函数,数据类型和变量
create or replace package tt_aa as
v1 varchar2(10);
v2 varchar2(10);
v3 number;
v4 boolean;
procedure proc1(x number);
procedure proc2(y varchar2);
procedure proc3(z number);
function my_add(x number,y number) return number;
end;
包主体(package body)是可选的
create or replace package body tt_aa as
procedure proc1(x number) as
begin
v1:=to_char(x);
end;
procedure proc2(y varchar2) as
begin
v2:=y;
end;
procedure proc3(z number) as
begin
v1:=z;
end;
procedure proc4(x number,y number) return number as
begin
return x+y;
end;
end;

调用
begin
tt_aa.proc1(6);
dbms_output.put_line(to_char(tt_aa.my_add(1,3));
end;
3、动态sql(使用dbms_sql)
create or replace procedure my_execute(sql_string in varchar2) as
v_cursor number;
v_numrows interger;
begin
v_cursor:=dbms_sql.open_cursor;
dbms_sql.parse(v_cursor,sql_string,dbms_sql.v7);
v_numrows:=dbms_sql.execute(v_cursor);
dbms_sql.close_cursor(v_cursor);
end;

则可以
sql>exec my_execute('select * from tab');
sql>exec my_execute('insert into test value'||'('||'''ddd'''||')');
sql>exec my_execute('commit');

对于查询方面的可以如下方式:
比如想用游标查询一个表,但是这个表是分月的,每个月可能表名都会改变。
create or replace procedure proc_test as
v_curid integer;
v_result integer;
v_strSql varchar2(255);
v_userid okcai.userid%type;
v_username okcai.username%type;
begin
v_strSql := 'select * from okcai_'||to_char(sysdate,'yyyymm');
v_curid := dbms_sql.open_cursor;
dbms_sql.parse(v_curid,v_strSql,dbms_sql.v7);
dbms_sql.define_column(v_curid,1,v_userid);
dbms_sql.define_column(v_curid,2,v_username,10); --必须指定大小
v_result := dbms_sql.execute(v_curid);
loop
if dbms_sql.fetch_rows(v_curid) = 0 then
exit; --没有了 ,退出循环
end if;
dbms_sql.column_value(v_curid,1,v_userid);
dbms_sql.column_value(v_curid,2,v_username);
dbms_output.put_line(v_userid);
dbms_output.put_line(v_username);
end loop;
dbms_sql.close(v_curid);
end;
4、用EXECUTE IMMEDIATE
<1>. 在PL/SQL运行DDL语句
begin
execute immediate 'set role all';
end;
<2>. 给动态语句传值(USING 子句)
declare
l_depnam varchar2(20) := 'testing';
l_loc varchar2(10) := 'Dubai';
begin
execute immediate 'insert into dept values (:1, :2, :3)'
using 50, l_depnam, l_loc;
commit;
end;
<3>. 从动态语句检索值(INTO子句)
declare
l_cnt varchar2(20);
begin
execute immediate 'select count(1) from emp'
into l_cnt;
dbms_output.put_line(l_cnt);
end;
<4>. 动态调用例程.例程中用到的绑定变量参数必须指定参数类型.�]认为IN类型,其它类型必须显式指定
declare
l_routin varchar2(100) := 'gen2161.get_rowcnt';
l_tblnam varchar2(20) := 'emp';
l_cnt number;
l_status varchar2(200);
begin
execute immediate 'begin ' || l_routin || '(:2, :3, :4); end;'
using in l_tblnam, out l_cnt, in out l_status;
if l_status != 'OK' then
dbms_output.put_line('error');
end if;
end;
<5>. 将返回值传递到PL/SQL记录类型;同样也可用%rowtype变量
declare
type empdtlrec is record (empno number(4),
ename varchar2(20),
deptno number(2));
empdtl empdtlrec;
begin
execute immediate 'select empno, ename, deptno ' ||
'from emp where empno = 7934'
into empdtl;
end;
<6>. 传递并检索值.INTO子句用在USING子句前
declare
l_dept pls_integer := 20;
l_nam varchar2(20);
l_loc varchar2(20);
begin
execute immediate 'select dname, loc from dept where deptno = :1'
into l_nam, l_loc
using l_dept ;
end;
<7>. 多行查询选项.对此选项用insert语句填充临时表,用临时表进行进一步的处理,也可以用REF cursors纠正此缺憾.
declare
l_sal pls_integer := 2000;
begin
execute immediate 'insert into temp(empno, ename) ' ||
' select empno, ename from emp ' ||
' where sal > :1'
using l_sal;
commit;
end;
<8>. 完成update的returning功能
update可以用returning返回修改以后的值。比如:
UPDATE employees
SET job_id =’SA_MAN’, salary = salary + 1000, department_id = 140
WHERE last_name = ’Jones’
RETURNING salary*0.25, last_name, department_id
INTO :bnd1, :bnd2, :bnd3;
用execute immediate来完成的时候,可以用
declare
l_sal pls_integer;
begin
execute immediate 'update employees SET salary = salary + 1000 where last_name=''okcai'' RETURNING INTO :1'
returning into v_sql;
commit;
end;

5、用ref cursor来完成动态游标的功能
declare
type ct is ref cursor;
cc ct;
v_notify acc_woff_notify%rowtype;
begin
open cc for 'select * from acc_woff_notify';
loop
fetch cc into v_notify;
exit when cc%notfound;
dbms_output.put_line(v_notify.done_code);
end loop;
close cc;
end;

6、重新编译
对失效的过程
sql>exec dbms_utility.compile_schema(schema);
如:
sql>exec dbms_utility.compile_schema(scott);
7.存储过程使用table类型
<1>.字符串数组
declare
type regionType is table of varchar2(3) index by binary_integer;
v_listRegion regionType;
i number(2):=0;
begin
v_listRegion(1):='571';
v_listRegion(2):='572';
v_listRegion(3):='573';
v_listRegion(4):='574';
v_listRegion(5):='575';
v_listRegion(6):='576';
v_listRegion(7):=null;
i := 1;
while i<= v_listRegion.last loop
dbms_output.put_line( v_listRegion(i) );
i := v_listRegion.next(i);
end loop;
end;
<2>.rowtype数组
declare
type CmUserType is table of cm_user%rowtype index by binary_integer;
v_listUser CmUserType;
i number(5):=0;
r_user cm_user%rowtype;
begin
i := 1;
for r_user in (select * from cm_user where rownum<=5) loop
v_listUser(i):= r_user;
i := i + 1;
end loop;
i := 1;
while i<= v_listUser.last loop
dbms_output.put_line( v_listUser(i).bill_id );
i := v_listUser.next(i);
end loop;
end;
<3>. record数组
declare
type recCmUserType is record (bill_id cm_user.bill_id%type,cust_name varchar2(25));
type CmUserType is table of recCmUserType index by binary_integer;
v_listUser CmUserType;
i number(5):=0;
r_user cm_user%rowtype;
begin
i := 1;
for r_user in (select * from cm_user where rownum<=5) loop
v_listUser(i).bill_id:= r_user.bill_id;
v_listUser(i).cust_name:= '客户'||i;
i := i + 1;
end loop;
i := 1;
while i<= v_listUser.last loop
dbms_output.put_line( v_listUser(i).bill_id );
dbms_output.put_line( v_listUser(i).cust_name );
i := v_listUser.next(i);
end loop;
end;
8、存储函数和过程

查看函数和过程的状态
SQL>select object_name,status from user_objects where object_type='FUNCTION';
SQL>select object_name,status from user_objects where object_type='PROCEDURE';

查看函数和过程的源代码
SQL>set long 1000
SQL>set pagesize 0
SQL>set trimspool on
SQL>select text from all_source where owner=user and name=upper('amp;plsql_name');

9、触发器

查看触发器
set long 50000;
set heading off;
set pagesize 2000;
select
'create or replace trigger "' ||
trigger_name || '"' || chr(10)||
decode( substr( trigger_type, 1, 1 ),
'A', 'AFTER', 'B', 'BEFORE', 'I', 'INSTEAD OF' ) ||
chr(10) ||
triggering_event || chr(10) ||
'ON "' || table_owner || '"."' ||
table_name || '"' || chr(10) ||
decode( instr( trigger_type, 'EACH ROW' ), 0, null,
'FOR EACH ROW' ) || chr(10) ,
trigger_body
from user_triggers;
10. 加密ORACLE的存储过程
用wrap命令,如:
下列存储过程内容放在AA.SQL文件中
create or replace procedure testCCB(i in number) as
begin
dbms_output.put_line('输入参数是'||to_char(i));
end;
SQL>wrap iname=a.sql;
PL/SQL Wrapper: Release 8.1.7.0.0 - Production on Tue Nov 27 22:26:48 2001
Copyright (c) Oracle Corporation 1993, 2000. All Rights Reserved.
Processing a.sql to a.plb
提示a.sql转换为a.plb,这就是加密了的脚本,执行a.plb即可生成加密了的存储过程
运行a.plb
SQL> @a.plb ;
11.怎么样利用游标更新数据
cursor c1 is
select * from tablename
where name is null for update [of column]
...
update tablename set column = ...
where current of c1;
但是如果这种方式打开以后做了commit,则下次fetch会报ora-01002错误
12.怎样自定义异常
pragma_exception_init(exception_name,error_number);
如果立即抛出异常
raise_application_error(error_number,error_msg,true|false);
其中number从-20000到-20999,错误信息最大2048B
异常变量
SQLCODE 错误代码
SQLERRM 错误信息
13.在pl/sql中执行DDL语句
<1>、8i以下版本dbms_sql包
<2>、8i以上版本还可以用
execute immediate sql;
dbms_utility.exec_ddl_statement('sql');
14.用java写存储过程包
<1>
create or replace and compile
java source
named "CHelloWorld" as
public class HelloWorld
{
public static String print()
{
return System.out.println("Hello,World");
}
};
/
<2>
create or replace function my_helloWorld return varchar2
as language java
name 'HelloWorld.print() return java.lang.String';
/
<3>
select my_helloWorld from dual;
分享到:
评论

相关推荐

    pl/sql数据库学习笔记

    pl/sql数据库学习笔记,包含一些基础知识,和案例代码

    oraclePL/SQL精华笔记

    此文档由个人总结快速学习pl/sql的案例及说明,也是快速查询pl、sql开发的精华文档,在此提供给大家学习与查阅

    PL/SQL学习笔记

    PL/SQL有三种集合 联合数组 嵌套表 可变数组 联合数组详解: 什么是数组?数组有什么特点 数据是线性存放的,在内存中地址是连续的 可以用索引来访问 定义联合数组? 联合数组不需要定义长度,他能容纳的元素最大...

    sql,PL/SQl学习笔记

    Oracle的学习笔记,很有用的啊!里面有sqlplus,PL/SQL.对编程的朋友很有用

    oracle PL-SQL 学习笔记2

    oracle PL-SQL 学习笔记 oracle PL-SQL 学习笔记

    我的PL/SQL学习笔记(一)

    关于一些PL/SQL的基础知识,有些代码用到了scott用户下的默认表emp和dept;

    oracle PL-SQL 学习笔记1

    oracle PL-SQL 学习笔记 很好的总结

    pl/sql学习笔记

    这是oracle学习的进阶部分,笔记很详细,相信对大家会有帮助的!

    Oracle笔记,主要是关于SQL以及PL/SQL部分

    最近学习Oracle时写的笔记,对于Oracle中常用的数据库对象、函数,常用语句,PL/SQL都有涉及到,学习的时候是看的动力节点的视频,其中部分知识点摘自网络

    Oracle 入门文档

    Oracle笔记 六、PL/SQL简单语句块、变量定义 Oracle笔记 七、PL/SQL 异常处理 Oracle笔记 八、PL/SQL跳转/判断/循环语句块 Oracle笔记 九、PL/SQL 游标的使用 Oracle笔记 十、PL/SQL存储过程 Oracle笔记 十一、...

    Oracle PL/SQL高级编程

    主要是Oracle过程,函数,触发器,游标,包学习中自己所做的一些笔记,希望能够让初学者做一些参考!

    pl/sqle学习笔记

    剔除了oracle书上讲的多余的部分,只把重要的内容给记录下来,方便自己使用

    成功之路:Oracle11g学习笔记.pdf

    在介绍Oracle系统管理的知识以后,将介绍与开发相关的内容(如PL/SQL基础知识、存储过程、函数、包等),并介绍数据库性能调整,《成功之路:Oracle 11g学习笔记》重点介绍SQL语句调优。SQL语句调优是《成功之路:Oracle...

    成功之路 Oracle 11g 中文学习笔记

    成功之路 Oracle 11g 中文学习笔记 专为开发人员编写,先引导开发新手熟悉Oracle环境,然后进入数据库开发,并要掌握项目开发的一些技巧。开发技巧展示是本书一大特色(这一点很值得资深的开发人员借鉴)! 本书共24...

    Java/JavaEE 学习笔记

    PL/SQL学习笔记............358 第一章 PL/SQL概述........................358 第二章 PL/SQL程序结构................359 第三章 PL/SQL数据类型................362 第四章 PL/SQL中的控制语句........368 第五章...

    oracle 学习笔记

    oracle 学习笔记 SQL 高级SQL PL/SQL的学习笔记

    oracle小小笔记

    一点学习笔记 关于oracle pl/sql的 第一次上传多多照顾

    linux oracle从零开始 学习笔记

    Linux简介 Linux命令 Linux远程连接工具 Oracle在linux下的安装 Oracle相关配置 Oracle常用命令 PL/SQL连接oracle 问题总结

    oracle学习笔记整理

    学习oracle知识笔记整理,包括pl/sql编程,过程、函数、游标开发等。

    精通Oracle 10g PL.SQL编程

    精通Oracle 10g PL.SQL编程电子书及学习笔记

Global site tag (gtag.js) - Google Analytics