PL/SQL 基础 ( 下 )
1. PL/SQL中的 SQL语句
- END语句与COMMIT等内容,没有任何关系。
- PL/SQL does not directly support data definition language( DDL ) statements, such as CREATE TA BLE, ALTER TABLE, or DROP TABLE.
- PL/SQL does not support data control language( DCL ) statements, such as GRANT or REVOKE.
- 每条 SQL语句后边都要有个 ; 分号.
- PL/SQL 可以通过设置 exception 来管理错误,例如 NO_DATA_FOUND , TOO_MANY_ROWS
2. SQL 游标 (简单介绍 )
A cursor is a private SQL work area.
2种类型 : 隐式游标,显式游标
隐式游标 : The Oracle server uses implicit cursors to parse and execute your SQL statements. ( Whenever you issue a SQL statement, the Oracle server opens an area of memory in which the command is parsed and executed. this area is called a cursor.
When the executable part of a block issues a SQL statement, PL/SQL creates an implicit cursor, which PL/SQL manages automatically.
显式游标 : Explicit cursors are explicitly declared by the programer. ( 以下为游标的属性 )
- SQL%ROWCOUNT
- SQL%FOUND
- SQL%NOTFOUND
- SQL%ISOPEN
注意此处 : 只是单纯的使用 SQL%ROWCOUNT , 并没有定义显示游标,因为这是隐式游标,证明 ORACLE在解析SQL语句时,使用隐式游标。
3. Transaction Control Statement
COMMIT [ WORK ];
SAVEPOINT savepoint_name;
ROLLBACK [WORK] ;
ROLLBACK [WORK] TO [SAVEPOINT] savepoint_name;
其中 : 貌似 WORK 没什么用.
4. 选择语句 & 循环语句
IF condition THEN
ELSIF condition THEN // 注意,此处 ELSIF , 没有那个E
ELSE
END IF; // 最后,结束要有 ; 分号
CASE selector
WHEN expression1 THEN result1 // 这后边什么符号也没有
WHEN expression2 THEN result2
……
WHEN expressionN THEN resultN
ELSE resultN+1
END ; // 要有 END 和 ; 分号
注意 NULL : not NULL 还是 NULL , 与 NULL 的计算也全部是 NULL ,
-- basic loop ( use the basic loop when the statements inside the loop must execute at least once )
LOOP
statement 1;
EXIT [WHEN condition] ;
END LOOP;
--while loop ( use the while loop if the condition has to be evaluated at the start of each iteration )
WHILE condition LOOP
statement1;
statement2;
…
END LOOP;
--for loop ( use a for loop if the number of iterations is known )
FOR counter IN [REVERSE] lower_bound..upper_bound LOOP // counter 不用自己定义,系统会直接定义 , REVERSE 表示递减, 否则表示递增,增减幅度 1
statement1;
statement2;
…
END LOOP;
例如 :
FOR i IN 1..3 LOOP
END LOOP; // 增 , i 不用定义
FOR i IN REVERSE 1..3 LOOP
END LOOPS // 减, 注意后边的区间不用去改,还是从低到高
--嵌套循环
循环之间可以互相嵌套,多层,可以使用 label 来跳到想要走的位置,label要放到对应代码的上边,
在 END LOOP 后边写上标志 ( inner_loop, outer_loop ) 是好习惯。
5. Composite Data Types
- PL/SQL records
- PL/SQL collections ( index by table , nested table, varray ) ( 貌似这种不常用 )
( 就是将多种相关的数据集中在一起看,比如 employeer, 有 name, salary, birthday, 等等,虽然 name, slary, birthday 他们的存储类型不同,但是由于相关性,所以将它们作为一个整体来看 )
TYPE type_name IS RECORD
( field_declaration, field_declaration );
identifier type_name;
例如 :
TYPE emp_record_type IS RECORD
( employee_id NUMBER(6) NOT NULL := 100,
last_name VARCHAR2(25),
job_id VARCHAR2(10),
salary NUMBER(8, 2) ) ;
emp_record emp_record_type;
emp_record.job_id := ‘ST_CLERK’;
这种十分类似C中的结构体
%ROWTYPE
DECLARE
emp_record employees%ROWTYPE;
to declare a record based on a collection of columns in a database table or view, you use the %ROWTYPE attribute.
使用 ROWTYPE 的好处,1) 可以动态变更,即当基表本身发生变更时,ROWTYPE会随之变更,2)特别是在你想要将全部内容都掉出去来时,可以使用 SELECT * FROM TABLE INTO 该类型,省去了很多打字操作。
INDEX BY Tables
由两部分组成 ( 主键和列 )
- Primary key of data type BINARY_INTEGER
- Column of scalar or record data type ( 1列,或者是标准类型列,或者是组合类型列 )
TYPE type_name IS TABLE OF
{column_type variable%TYPE | table.column%TYPE | table.%ROWTYPE} [INDEX BY BINARY_INTEGER] ;
identifier type_name;
例如 :
TYPE ename_table_type IS TABLE OF
employees.last_name%TYPE
INDEX BY BINARY_INTEGER ;
ename_table ename_table_type;
( 有点像 XML )
如果定义为 INDEX BY Table 类型,会有很多方法, EXISTS , NEXT, COUNT, TRIM, FIRST AND LAST, DELETE, PRIOR
6. 权限管理相关内容
system privileges 包含 CREATE or ANY 关键字的是 系统权限
系统权限是由 SYS, SYSTEM 给予的,
Object privilege are rights assigned to a specific object within a shema and always include the name of object.
如果想创建 subprogram ( procedure , function ) , 必须有 CREATE PROCEDURE quanxian ,
if a PL/SQL subprogram refers to any objects that are not in the same schema, you must be granted access on these explicity, not through a role.
如果想调用 subprogram , 必须要有 EXECUTE object privilege.
Stored Information |
Description |
Access Method |
General | Object information | The USER_OBJECTS 数据字典 |
Source code | Text of the procedure | USER_SOURCE |
Parameters | IN / OUT / IN OUT datatype | describe command |
P-code | Compiled object code | Not accessible |
Compile errors | PL/SQL syntax errors | USER_ERRORS |
Run-time debug information | User-specified debug variables and messages | The DBMS_OUTPUT |
可以使用 show errors , 查看编译错误,( 这些内容也是存储在 USER_ERRORS 中的 )
DESCRIBE query_employee ( 查看 procedure 等内容, 跟 desc table_name 差不多 )
也可以是用 DBMS_OUTPUT 来显示内容,调试使用 ( 类似到处的 printf , 查看某些变量的内容 )
- 提示内容1 :Message upon entering, leaving a procedure, or indicating that an operation has occured
- 提示内容2 :Counter for a loop
- 提示内容3 :Value for a variable before and after an assignment.
DBMS_DEBUG ( 一些工具, 例如 PL/SQL DEVELOPER, 提供单步跟踪等等 )