一.概念:
游标:用来查询数据库,获取记录集合(结果集)的指针,可以让开发者一次访问一行结果集,在每条结果集上作操作。
二.分类:
1.静态游标:显式游标和隐式游标。
2.REF游标:是一种引用类型,类似于指针。
三.详细内容:
1.显式游标:
CURSOR游标名(参数) [返回值类型] IS Select语句生命周期:
a.打开游标(OPEN)解析,绑定。。。不会从数据库检索数据
b.从游标中获取记录(FETCH INTO)执行查询,返回结果集。通常定义局域变量作为从游标获取数据的缓冲区。
c.关闭游标(CLOSE)完成游标处理,用户不能从游标中获取行。还可以重新打开。
选项:参数和返回类型
DECLARE
CURSOR emp_cur (p_deptid IN NUMBER)
IS
SELECT *
FROM employees
WHERE department_id = p_deptid;
l_emp employees%ROWTYPE;
BEGIN
DBMS_OUTPUT.put_line ('Getting employees from department 30');
OPEN emp_cur (30);
LOOP
FETCH emp_cur
INTO l_emp;
EXIT WHEN emp_cur%NOTFOUND;
DBMS_OUTPUT.put_line ('Employee id ' || l_emp.employee_id || ' is ');
DBMS_OUTPUT.put_line (l_emp.first_name || ' ' || l_emp.last_name);
END LOOP;
CLOSE emp_cur;
DBMS_OUTPUT.put_line ('Getting employees from department 90');
OPEN emp_cur (90);
LOOP
FETCH emp_cur
INTO l_emp;
EXIT WHEN emp_cur%NOTFOUND;
DBMS_OUTPUT.put_line ('Employee id ' || l_emp.employee_id || ' is ');
DBMS_OUTPUT.put_line (l_emp.first_name || ' ' || l_emp.last_name);
END LOOP;
CLOSE emp_cur;
END;
2.隐式游标:不用明确建立游标变量,分两种:a.在PL/SQL中使用DML语言,使用ORACLE提供的名为SQL的隐示游标b.CURSOR FOR LOOP,用于for loop语句
a.举例:
DECLARE
BEGIN
UPDATE c_order t
SET t.description = 'haha'
WHERE 1 = 2;
IF SQL%NOTFOUND
THEN
DBMS_OUTPUT.put_line ('no records!');
ELSE
DBMS_OUTPUT.put_line ('update ' || SQL%ROWCOUNT || ' records');
END IF;
END;
b.举例:
DECLARE
BEGIN
FOR my_dept_rec IN (select documentno from c_order)
LOOP
DBMS_OUTPUT.put_line ('haha');
END LOOP;
END;
c.举例:
单独select
DECLARE
orderid c_order.c_order_id%TYPE;
BEGIN
SELECT c_order_id
INTO orderid
FROM c_order
WHERE ROWNUM = 1;
DBMS_OUTPUT.put_line (orderid);
END;
使用INTO获取值,只能返回一行。
游标属性:
%FOUND:变量最后从游标中获取记录的时候,在结果集中找到了记录。%NOTFOUND:变量最后从游标中获取记录的时候,在结果集中没有找到记录。%ROWCOUNT:当前时刻已经从游标中获取的记录数量。%ISOPEN:是否打开。
显式和隐式游标的区别:
尽量使用隐式游标,避免编写附加的游标控制代码(声明,打开,获取,关闭),也不需要声明变量来保存从游标中获取的数据。
3.REF CURSOR游标:
动态游标,在运行的时候才能确定游标使用的查询。分类:1.强类型(限制)REF CURSOR,规定返回类型2.弱类型(非限制)REF CURSOR,不规定返回类型,可以获取任何结果集。
强类型举例:
DECLARE
--声明记录类型
TYPE emp_job_rec IS RECORD (
ID NUMBER,
docno VARCHAR2 (50)
);
--声明REF CURSOR,返回值为该记录类型
TYPE emp_job_refcur_type IS REF CURSOR
RETURN emp_job_rec;
--定义REF CURSOR游标的变量
emp_refcur emp_job_refcur_type;
--定义记录类型变量
emp_job emp_job_rec;
BEGIN
OPEN emp_refcur FOR
SELECT e.c_order_id, e.documentno
FROM c_order e
WHERE ROWNUM < 11
ORDER BY 1;
FETCH emp_refcur
INTO emp_job;
WHILE emp_refcur%FOUND
LOOP
DBMS_OUTPUT.put_line ( 'ID = ' || emp_job.ID
|| ' ' || 'DocNo = ' || emp_job.docno
);
FETCH emp_refcur
INTO emp_job;
END LOOP;
END;
DECLARE
--声明REF CURSOR,返回值rowtype
TYPE emp_job_refcur_type IS REF CURSOR
RETURN c_order%ROWTYPE;
--定义REF CURSOR游标的变量
emp_refcur emp_job_refcur_type;
--定义rowtype变量
emp_job c_order%ROWTYPE;
BEGIN
OPEN emp_refcur FOR
SELECT e.*
FROM c_order e
WHERE ROWNUM < 11
ORDER BY 1;
FETCH emp_refcur
INTO emp_job;
WHILE emp_refcur%FOUND
LOOP
DBMS_OUTPUT.put_line (emp_job.documentno);
FETCH emp_refcur
INTO emp_job;
END LOOP;
END;
游标:用来查询数据库,获取记录集合(结果集)的指针,可以让开发者一次访问一行结果集,在每条结果集上作操作。
二.分类:
1.静态游标:显式游标和隐式游标。
2.REF游标:是一种引用类型,类似于指针。
三.详细内容:
1.显式游标:
CURSOR游标名(参数) [返回值类型] IS Select语句生命周期:
a.打开游标(OPEN)解析,绑定。。。不会从数据库检索数据
b.从游标中获取记录(FETCH INTO)执行查询,返回结果集。通常定义局域变量作为从游标获取数据的缓冲区。
c.关闭游标(CLOSE)完成游标处理,用户不能从游标中获取行。还可以重新打开。
选项:参数和返回类型
DECLARE
CURSOR emp_cur (p_deptid IN NUMBER)
IS
SELECT *
FROM employees
WHERE department_id = p_deptid;
l_emp employees%ROWTYPE;
BEGIN
DBMS_OUTPUT.put_line ('Getting employees from department 30');
OPEN emp_cur (30);
LOOP
FETCH emp_cur
INTO l_emp;
EXIT WHEN emp_cur%NOTFOUND;
DBMS_OUTPUT.put_line ('Employee id ' || l_emp.employee_id || ' is ');
DBMS_OUTPUT.put_line (l_emp.first_name || ' ' || l_emp.last_name);
END LOOP;
CLOSE emp_cur;
DBMS_OUTPUT.put_line ('Getting employees from department 90');
OPEN emp_cur (90);
LOOP
FETCH emp_cur
INTO l_emp;
EXIT WHEN emp_cur%NOTFOUND;
DBMS_OUTPUT.put_line ('Employee id ' || l_emp.employee_id || ' is ');
DBMS_OUTPUT.put_line (l_emp.first_name || ' ' || l_emp.last_name);
END LOOP;
CLOSE emp_cur;
END;
2.隐式游标:不用明确建立游标变量,分两种:a.在PL/SQL中使用DML语言,使用ORACLE提供的名为SQL的隐示游标b.CURSOR FOR LOOP,用于for loop语句
a.举例:
DECLARE
BEGIN
UPDATE c_order t
SET t.description = 'haha'
WHERE 1 = 2;
IF SQL%NOTFOUND
THEN
DBMS_OUTPUT.put_line ('no records!');
ELSE
DBMS_OUTPUT.put_line ('update ' || SQL%ROWCOUNT || ' records');
END IF;
END;
b.举例:
DECLARE
BEGIN
FOR my_dept_rec IN (select documentno from c_order)
LOOP
DBMS_OUTPUT.put_line ('haha');
END LOOP;
END;
c.举例:
单独select
DECLARE
orderid c_order.c_order_id%TYPE;
BEGIN
SELECT c_order_id
INTO orderid
FROM c_order
WHERE ROWNUM = 1;
DBMS_OUTPUT.put_line (orderid);
END;
使用INTO获取值,只能返回一行。
游标属性:
%FOUND:变量最后从游标中获取记录的时候,在结果集中找到了记录。%NOTFOUND:变量最后从游标中获取记录的时候,在结果集中没有找到记录。%ROWCOUNT:当前时刻已经从游标中获取的记录数量。%ISOPEN:是否打开。
显式和隐式游标的区别:
尽量使用隐式游标,避免编写附加的游标控制代码(声明,打开,获取,关闭),也不需要声明变量来保存从游标中获取的数据。
3.REF CURSOR游标:
动态游标,在运行的时候才能确定游标使用的查询。分类:1.强类型(限制)REF CURSOR,规定返回类型2.弱类型(非限制)REF CURSOR,不规定返回类型,可以获取任何结果集。
强类型举例:
DECLARE
--声明记录类型
TYPE emp_job_rec IS RECORD (
ID NUMBER,
docno VARCHAR2 (50)
);
--声明REF CURSOR,返回值为该记录类型
TYPE emp_job_refcur_type IS REF CURSOR
RETURN emp_job_rec;
--定义REF CURSOR游标的变量
emp_refcur emp_job_refcur_type;
--定义记录类型变量
emp_job emp_job_rec;
BEGIN
OPEN emp_refcur FOR
SELECT e.c_order_id, e.documentno
FROM c_order e
WHERE ROWNUM < 11
ORDER BY 1;
FETCH emp_refcur
INTO emp_job;
WHILE emp_refcur%FOUND
LOOP
DBMS_OUTPUT.put_line ( 'ID = ' || emp_job.ID
|| ' ' || 'DocNo = ' || emp_job.docno
);
FETCH emp_refcur
INTO emp_job;
END LOOP;
END;
DECLARE
--声明REF CURSOR,返回值rowtype
TYPE emp_job_refcur_type IS REF CURSOR
RETURN c_order%ROWTYPE;
--定义REF CURSOR游标的变量
emp_refcur emp_job_refcur_type;
--定义rowtype变量
emp_job c_order%ROWTYPE;
BEGIN
OPEN emp_refcur FOR
SELECT e.*
FROM c_order e
WHERE ROWNUM < 11
ORDER BY 1;
FETCH emp_refcur
INTO emp_job;
WHILE emp_refcur%FOUND
LOOP
DBMS_OUTPUT.put_line (emp_job.documentno);
FETCH emp_refcur
INTO emp_job;
END LOOP;
END;