您好,欢迎来到九壹网。
搜索
您的当前位置:首页PLSQL笔记

PLSQL笔记

来源:九壹网
一、基础与概念

1、PL/SQL不区分大小写,除非是由引号引起来的字符串。 2、 PL/SQL标识符的命名规则

标识符的最大长度是30个字符,包括字母,数字,$,_,#

不可包含保留字 要以字来打头

不能和同一块中的表中的字段名一样

3、命名规范

sql*plus substitution variable p_name variable v_name constant c_name

sql*plus global variable g_name exception e_name 4、注销方式

--注释内容

/*……注释内容………….*/

5、只要表达式里有NULL,则整个表达式的值为NULL BOOLEAN和NULL

这里要注意的是:NULL AND TRUE ==NULL NULL AND FALSE==FALSE NULL OR TRUE==TRUE NULL OR FALSE ==NULL 6、PL/SQL Environment

PL/SQL Blcok-----mon-sql-----procedural statement executor -----sql------------sql statement executor

7、分类

procedures:执行一个动作,做为一个pl/sql来执行,可以返回一个值 function:计算一个值,用于嵌入到表达式中,并必须返回一个值 package:把函数和过程逻辑的关联起来

8、pl/sql block structure

header: Contains the subprogram name, type, and arguments.Only used for subprograms.

Declarative: Contains the local identifiers for the block.

Executable: Contains the SQL statements and PL/SQL control statements.

Exception: Performs actions when errors occur.

9、 DCL和DDL都不被pl/sql支持。DML和commit可以被支持. 10、一个嵌套块成为封闭块里的一个可执行语句,一个块可嵌套在任何允许放置可执行语句的地方,包括执行部分和异常处理部分。

11、PL/SQL表达式不能包含组函数,但一个PL/SQL块里的SQL语句可以。 12、当一个语句中有混合的数据类型时,PL/SQL可以动态转变。如:想把一个NUMBER值存进一个VARCHAR2的变量里,PL/SQL会动态地把NUMBER值转变为VARCHAR2类型的字符值。

13、PL/SQL表达式可以包含SQL函数。 14、嵌套块里的语句不能包含一个异常段。

15、PL/SQL中的SELECT语句必须使用INTO子句。

二、 数据类型:

1) Base Scalar Datatypes•

 VARCHAR2 :在PL/SQL中可以存储2000,在oracle8中是4000字节  NUMBER [(precision, scale)]:当声明时。默认值是null  DATE:存储日期型  CHAR [(maximum_length)]: 如没有指定,数据类型为CHAR的列默认

长度为1。这个长度的范围是1到2000。

 LONG:用于长度不定,最大值为2G的字符型数据。  Row用来存二进制,在PL/SQL中最大长度是32767,在oracle8中是

255字节

 LONG RAW:可以容纳raw binary data

 BOOLEAN:只能为true or false or null  BINARY_INTEGER  PLS_INTEGER

2) Composite Datatypes

 PL/SQL TABLES:

Primary Key:KEY的类型是BINARY_INTEGER VALUE:真正的值

声明:TYPE type_name IS TABLE OF {column_type | variable%TYPE | table.column%TYPE} [NOT NULL] [INDEX BY BINARY_INTEGER];

identifier type_name;

eg1:TYPE t_nametable IS TABLE OF VARCHAR(2) INDEX BY BINARY_INTEGER; 引用:t_nametable(1):=’jact’ eg2:

DECLARE

TYPE dept_table_type IS TABLE OF dept%ROWTYPE INDEX BY BINARY_INTEGER; dept_table dept_table_type;

引用:dept_table.row1(1):=’jact’;  PL/SQL RECORDS

定义: TYPE type_name IS RECORD

(field_declaration[, field_declaration]…); identifier type_name;

TYPE record_name IS RECORD(

name varchar(20), id number(9)

)

引用:

student record_name student.name student.id

3) 3)Lob: 用来存二进制,最大长度是4GB

CLOB:RECIPE

BLOB:PHOTO(可以容纳4G的二进制)

BFILE:MOVIE把二进制存在一个扩展的文件中。容量是4G NCLOB

三、PL/SQL Block Structure

DECLARE---Optional

-Variables,Constants,cursors,user-defined exceptions BEGIN---Mandatory

-SQL statements

-PL/SQL control statements EXCEPTION-Optional

-Actions to perform when errors occur END:---Mandatory

Block type

Anonymous:[DECLARE] BEGIN

……..

[EXCEPTION] END;

Procedure:PROCEDURE name IS [DECLARE] BEGIN

……..

[EXCEPTION] END;

Function:FUNTION name

RETURN datatype IS [DECLARE] BEGIN

……..

RETURN value;

[EXCEPTION] END;

四、变量

1、变量的赋值:identifier [CONSTANT] datatype [NOT NULL] [:= | DEFAULT expr];

2、变量名number(9,2) NOT NULL :=0; //在声明一个PL/SQL参数时,可以使用

赋值运算符 := 为该参数赋初值。如果没有为参数赋初值,参数会被设置为null。如果参数被定义NOT NULL约束,那么就必须赋初值。

3、变量的类型:变量名number(9,2);

变量名 saray%type; //这样value的类型就和saray一样,也可

以用列名取代saray

变量名parts%rowtype

//parts是表名,这是个记录类型的变量。其内部结构和parts一样

是根据表或视图的列来定义各变量 用表名做为前缀 结构和表的结构一样

4、在PL/SQL调用sqlplus的变量,在变量前面加”:”

:g_monthly_sal := v_sal / 12;

五、控制程序流

1、 loop

程序段

exit [ when 表达式] end loop;

可以为循环设定标签 EG:

BEGIN

<> LOOP

v_counter := v_counter+1; EXIT WHEN v_counter>10; <> LOOP ...

EXIT Outer_loop WHEN total_done = 'YES'; -- Leave both loops

EXIT WHEN inner_done = 'YES'; -- Leave inner loop only ...

END LOOP Inner_loop; ...

END LOOP Outer_loop; END;

2、 while 表达式 loop

程序段 end loop;

3、for I in 1 .. 20 loop

程序段 end loop; 4、if [not]…..then

程序段

elsif ….then 程序段 else

程序段 end if;

5、 message1

<> a:=a+1

注意:不可以同外层跳到里层

不可以从一个IF子句跳到另一个IF子句 不可以从异常处理块跳到当前块

6、 select into 为变量赋值

select name into v_name where …

六、游标

游标的本质是SQL语句的一个工作区域,用于处理多行记录集的查询。 分类:Implicit cursors:由DML和PL/SQL的SELECT隐式的定义,不可以使用open,fetch

和close去控制这个sql 游标。每一次只处理一行。但是可以使用游标的属性

Explicit cursors:由程序员定义, 显式游标用于返回多于一行的查询

以下讨论的都是显式游标 执行的四个步骤:

1、声明:定义游标的名字和结构,select 中可以使用order by 2、 打开游标:执行查询同时绑定所有涉及到的变量

执行的内容:

为select 分配内存并分析select语句 绑定输入的变量

配置指针在活动集的第一行

注意:如果 查询不返回结果,不会引发PL/SQL的异常,你可以在执行fetch后

测试返回的结果

如果游标内的声明包括update。一样会执行行锁定

3、 Fetch:把当前行的值赋给变量,每个fetch都会把游标指针向下移动一行。 如果到了最后一行就会自动退出for loop

4、

关闭:释放活动的集,可以再次使用open

游标的几个属性:

SQL%ROWCOUNT 受最近执行的SQL语句影响的行的数目。(一个整数值)

SQL%FOUND Boolean属性,如果最近的SQL语句影响了一行或多行,其值为 TRUE。

SQL%NOTFOUND Boolean属性,如果最近的SQL语句没有影响任何行,其值为 TRUE。

SQL%ISOPEN 总是为FALSE,原因是PL/SQL总是它们结束执行后立即关闭内隐游标。

例子

EG1:常规用法

CURSOR c1 IS

SELECT empno, ename FROM emp;

emp_record c1%ROWTYPE; BEGIN

OPEN c1; . . .

FETCH c1 INTO emp_record;

EG2:使用for循环实现游标

DECLARE

CURSOR c1 IS

SELECT empno, ename

FROM emp;

emp_record c1%ROWTYPE; BEGIN

FOR emp_record IN c1 LOOP

-- implicit open and implicit fetch occur IF emp_record.empno = 7839 THEN ...

END LOOP; -- implicit close occurs END;

游标FOR循环立时不需要FETCH语句的。游标打开,在循环中每次重复提取一行,所有的行都处理后,游标会自动关闭。

EG3:不定义游标的方式

BEGIN

FOR emp_record IN ( SELECT empno, ename FROM emp) LOOP

-- implicit open and implicit fetch occur IF emp_record.empno = 7839 THEN ...

END LOOP; -- implicit close occurs END;

EG4:带变量的游标------ 你必须指定指定参数的数据类型,但不用指定大小

DECLARE

CURSOR c1

(v_deptno NUMBER, v_job VARCHAR2) IS SELECT empno, ename FROM emp

WHERE deptno = v_deptno AND job = v_job; BEGIN

OPEN c1(10, 'CLERK'); ...

EG5:FOR UPDATE----当加上for update则把整个表或字段锁住了。

SELECT ... FROM ...

FOR UPDATE [OF column_reference][NOWAIT]

DECLARE

CURSOR c1 IS

SELECT empno, ename FROM emp

FOR UPDATE NOWAIT;

NOWAIT:返回一个oracle的错误信息如果此行给其他的会话锁住了。

EG6:WHERE CURRENT OF

用于在游标中删除和更新当前行 必须使用 FORUPDATE去锁住行

使用WHERE CURRENT OF去指向当前的行 DECLARE

CURSOR c1 IS SELECT ...

FOR UPDATE NOWAIT; BEGIN ...

FOR emp_record IN c1 LOOP UPDATE ...

WHERE CURRENT OF c1; ... END LOOP; COMMIT; END;

七、处理异常

Predefined Exception

BEGIN SELECT ... COMMIT; EXCEPTION

WHEN NO_DATA_FOUND THEN

statement1;

statement2; WHEN TOO_MANY_ROWS THEN statement1; WHEN OTHERS THEN statement1; statement2; statement3; END; …….

Non-Predefined Exception

DECLARE

e_products_invalid EXCEPTION; PRAGMA EXCEPTION_INIT (

e_products_invalid, -2292); v_message VARCHAR2(50); BEGIN . . . EXCEPTION

WHEN e_products_invalid THEN :g_message := 'Product code specified is not valid.'; . . . END;

User-Defined Exception

DECLARE

e_amount_remaining EXCEPTION; . . . BEGIN . . .

RAISE e_amount_remaining; . . . EXCEPTION

WHEN e_amount_remaining THEN

:g_message := 'There is still an amount in stock.'; . . . END;

RAISE_APPLICATION_ERROR

DECLARE …….

Invalidpart EXCEPTION; BEGIN

    

…….

IF SQL%NOTFOUND THEN RAISE invalidpart; END IF; EXCEPTION

WHEN invalidpart THEN

Raise_application_error(-20003,’Invalid Part id #’|| partnum); WHEN OTHERS THEN

Raise_application_error(-20000,errNum||errMsg); END

使用EXCEPTION关键字在一个PL/SQL块的声明部分声明用户自定义异常 使用PL/SQL命令RAISE检测用户自定义异常

PL/SQL可使用Raise_application_error过程返回一个用户自定义错误数和消息给调用环境。所有的用户自定义错误消息必须在-20000到-20999之间

PL/SQL程序可以使用WHEN OTHERS 异常处理来处理没有特定处理的所有异常 PL/SQL程序可以使用特殊的SQLCODE和SQLERRM函数返回最新的oracle错误号码和消息

DECLARE

v_error_code NUMBER;

v_error_message VARCHAR2(255); BEGIN ...

EXCEPTION ...

WHEN OTHERS THEN ROLLBACK;

v_error_code := SQLCODE ; v_error_message := SQLERRM ;

INSERT INTO errors VALUES(v_error_code, v_error_message); END;

数据库联接

定义:CREATE DATABASE LINK link_name

CONNECT TO username IDENTIFIED BY password

USING sqlnet_string;

使用:表名@link_name

替代名

CREATE SYNONYM synonym_name FOR reference; Eg:CREATE SYNONYM backup FOR backup@esal

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 91gzw.com 版权所有 湘ICP备2023023988号-2

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务