oracle查询数据都是以数据集的形式取出。如何对数据集中的数据进行处理,cursor就是答案。
游标分为显式游标和隐式(游标变量)两种。前者属于静态游标,一般处理的数据时定义时候就确定的,而游标变量在使用时才确定要处理哪
些数据,灵活性很大。
显式游标:
语法:Cursor cursor_name is [select.. segment] [return type]
[for update] [of segment][nowait];
[select.. segment]指定查询语句,[return type]指定返回类型,如果不知道,那么可以返回任何类型,但是一旦指定,就必须只返回指定
的类型。当试图用游标给修改数据或者删除数据时,需要指定for update。并且在修改语句中加上where current of cursor_name;[of
segment]指定加锁的表或者行,如果不知道,那么oracle将对游标涉及的所有表加上共享表,不允许其他用户的DML操作。[nowait]表示如果
需要的表或者行正在被其它事务使用,不等待其释放锁,立即返回,并报一个错。
DECLARE
CURSOR CURSOR_ALL4 IS SELECT PID,CUS_NAME,PRICE FROM Purchase ORDER BY PRICE DESC;
pid Purchase.Pid%type;
cus_name Purchase.Cus_Name%type;
price Purchase.Price%type;
begin
IF NOT CURSOR_ALL4%ISOPEN THEN
open CURSOR_ALL4;
END IF;
loop
fetch CURSOR_ALL4 into pid,cus_name,price;
dbms_output.put_line('商品编号:'||pid||','||'客户姓名:'||cus_name||','||'商品价格:'||price);
exit when cursor_all4%notfound;
end loop;
DBMS_OUTPUT.PUT_LINE('一共有'||CURSOR_ALL4%ROWCOUNT||'行');
end;
游标每次读取一行数据,可以使用bulk collect将所有数据一次性批量输出:
DECLARE
CURSOR CUR_1 IS SELECT CUS_NAME FROM Purchase ;
TYPE TABLETYPE IS TABLE OF Purchase.Cus_Name%type;
T1 TABLETYPE;
BEGIN
OPEN CUR_1;
LOOP
FETCH CUR_1 BULK COLLECT INTO T1;
FOR I IN 1..T1.COUNT LOOP
DBMS_OUTPUT.put_line(T1(I));
END LOOP;
EXIT WHEN CUR_1%NOTFOUND;
END LOOP;
CLOSE CUR_1;
END;
DECLARE
CURSOR CUR_2 IS SELECT * FROM TEMP1 FOR UPDATE ;
PID TEMP1.PID%TYPE;
BEGDATE TEMP1.BEGINDATE%TYPE;
ENDDATE TEMP1.ENDDATE%TYPE;
BEGIN
IF NOT CUR_2%ISOPEN THEN
OPEN CUR_2;
END IF;
LOOP
FETCH CUR_2 INTO PID,BEGDATE,ENDDATE;
IF (ENDDATE-BEGDATE)>15 THEN
DBMS_OUTPUT.put_line(PID||','||BEGDATE||','||ENDDATE);
UPDATE TEMP1 SET ENDDATE=BEGINDATE+15 WHERE CURRENT OF CUR_2;
END IF;
EXIT WHEN CUR_2%NOTFOUND;
END LOOP;
END;
1 | 2012-9-6 | 2012-9-21 |
3 | 2012-9-6 | 2012-9-21 |
2 | 2012-9-6 | 2012-9-20 |
游标变量:
DECLARE
TYPE CUR_TYPE IS REF CURSOR;
CUR_3 CUR_TYPE;
TYPE TABLE_TYPE2 IS TABLE OF Date;
T2 TABLE_TYPE2;
BEGIN
OPEN CUR_3 FOR SELECT BEGINDATE FROM TEMP1;
LOOP
FETCH CUR_3 BULK COLLECT INTO T2;
FOR I IN 1..T2.COUNT LOOP
DBMS_OUTPUT.put_line(T2(I));
END LOOP;
EXIT WHEN CUR_3%NOTFOUND;
END LOOP;
CLOSE CUR_3;
END;
06-9月 -12
06-9月 -12
06-9月 -12