目录
复合数据类型
复数据类型包括:
- 记录
- 关联数组(index by表)
- 嵌套表
- 可变长度数组
PL/SQL 记录
和C++中的结构体比较像。
它是有几个相关值构 成的复合变量,是表中单行数据结构的一个镜像,可用于支持SELECT语句的返回值。记录 将一行数据看成一个单元,而不是将每一列单独处理
定义
TYPE record_type IS RECORD
(
Variable_1 datatype1[,
Variable_2 datatype2[, ...]]
);
注意这样定义的是类型,还要再定义这个类型的变量。
例:
DECLARE
TYPE NewRecordTYPE IS RECORD
(
id number,
name varchar2(10)
);
recTest NEWRECORDTYPE;
BEGIN
SELECT empno,ename INTO recTest
FROM emp WHERE empno=7369;
DBMS_OUTPUT.PUT_LINE
(recTest.id||'号员工的姓名是'||recTest.name);
END;
%ROWTYPE属性
声明的变量对应于数据库表或视图中列的集合。在%ROWTYPE之前加上数据库表名。字段表示表中的列。
这种数据类型可以一个变量把整个表的东西读出来,用".元素名"使用。
DECLEAR
emp_rec emp%rowtype;
BEGIN
select * into emp_rec
from emp
where empno=7788;
INSERT INTO test VALUES
(emp_rec.EMPNO,emp_rec.ENAME,...,)
commit;
END;
游标
游标是一种PL/SQL控制结构,可以对SQL语句 的处理进行显式控制,便于对游标的行数据逐条进行处理。
分为隐式游标和显式游标。
例如删除数据时删除掉多少行数据,就通过隐式游标来获得。
隐式游标
从EMP中删除指定部门,返回删除的行的数量。
DECLARE
v_deptno NUMBER := 20;
v_rows_deleted VARCHAR2(30);
BEGIN
DELETE FROM emp
WHERE deptno = v_deptno;
v_rows_deleted := SQL%ROWCOUNT;
dbms_output.put_line(v_rows_deleteed || 'rows deleted.');
END;
显示游标
需要自己定义打开显示关闭。
理解:游标存在指针,从刚开始指向第一条,逐渐移动来遍历结果集。
操作:
- 定义游标
- 打开游标
- 提取游标
- 关闭游标
注意:一点特殊的是,遍历到的结果集不能再取了,即只能顺着遍历,不能倒回来看。
声明
CURSOR cur_name IS
select statement
打开游标
OPEN cur_name
提取游标
FETCH cur_name INTO [variable1,variable2,...]
关闭游标
关闭游标释放占用的内存空间,不写也是不出问题的。
CLOSE cur_name
例子:
DECLARE
v_ename emp.name%TYPE;
v_sal emp.sal%TYPE;
CURSOR cur_emp IS
select ename,sal
from emp
where sal>2000;
BEGIN
OPEN cur_emp;
FETCH cur_emp INTO v_ename,v_sal;
dbms_output.putline(v_ename || ' ' || v_sal);
FETCH cur_emp INTO v_ename,v_sal;
dbms_output.put_line(v_ename || ' ' || v_sal;
CLOSE cur_emp;
END;
显示游标的属性
属性 | 类型 | 描述 |
%ISOPEN | bool | 游标打开的为TRUE |
%NOTFOUND | bool | FETCH语句没有返回数据是TRUE |
%FOUND | bool | FETCH返回一行记录则为TRUE |
%ROWCOUNT | 数值 | 返回到现在为止从游标中取出的记录数目 |
例子
DECLARE
v_ename emp.name%TYPE;
v_sal emp.sal%TYPE;
CURSOR cur_emp IS
select ename,sal
from emp
where sal>2000;
BEGIN
IF NOT cur_emp%ISOPEN THEN
OPEN cur_emp;
END IF;
LOOP
FETCH cur_emp INTO v_ename,v_sal;
EXIT WHEN cur_emp%NOTFOUND;
dbms_output.putline(cur_emp%ROWCOUNT);
dbms_output.put_line(v_ename || ' ' || v_sal);
END LOOP;
CLOSE cur_emp;
END;
游标和for循环
- 游标式的for循环可以方便的处理显示游标。
- 隐式的打开提取和关闭游标。
- 隐式声明记录类型变量。
DECLARE
CURSOR emp_cursor IS
SELECT empno,ename FROM emp;
BEGIN
FOR emp_record IN emp_cursor LOOP
dbms_opyput.putline(emp_record.empno);
END LOOP;
END;
带参数的游标
每次传入不同值可以获得不同的结果集。更灵活
DECLARE
CURSOR cur_emp (p_sal NUMBER) IS
select ename,sal
from emp
where sal>2000;
BEGIN
FOR rec_emp IN cur_emp(2000) LOOP
dbms_output.put_line(v_ename || ' ' || v_sal);
END LOOP;
END;
简单循环
DECLARE
CURSOR cur_emp (p_sal NUMBER) IS
select ename,sal
from emp
where sal>2000;
rec_emp cur_emp%ROWTYPE
BEGIN
OPEN cur_emp(3000);
LOOP
FETCH cur_emp INTO rec_emp;
EXIT when cur_emp%NOTFOUND;
dbms_output.put_line(v_ename || ' ' || v_sal);
END LOOP;
CLOSE cur_emp;
END;
FOR UPDATE 子句
用游标对结果集进行修改。期间需要加锁以拒绝访问。
语法
SELECT ...
FROM ...
FOR UPDATE [OF column_reference][NOWAIT];
noway表示其他请求无需等待,直接返回错误。
SELECT *
FROM emp
WHERE empno=7788
FOR UPDATE nowait;