游标可以处理SQL语句查询出来的结果集,进行逐条控制,其实游标在内存中申请空间,将自己指向SQL语句查询出来的结果集,有点像指针的感觉,游标使SQL更加的灵活。
DECLARE CURSOR mycur IS --申请内存 SELECT * FROM books; --查出结果集 要实现对结果逐条处理 myrecord books%ROWTYPE; --准备变量 用于游标取出的数据的存储 因为取出表中所有的字段采取%ROWTYPE记 录的方式 BEGIN
OPEAN mycur; --打开游标结果集
FETCH mycur INTO myrecord; --将结果集存在变量中 取得是SELECT语句结果集的第一条
WHILE mycur%FOUND LOOP --如果游标中有数据则执行循环 在LOOP前必须先有FETCH语句 才能判断是否有据
DBMS_OUTPUT.PUT_LINE(myrecord.books_id||','||myrecord.books_name); --输出字段 ||为连接字符串的 像是'+' 也可以连接不同类型的变量
FETCH mycur INTO myrecord;
END LOOP;
CLOSE mycur;
END;
/
游标属性:
%FOUND 表示游标里是否有数据可取布尔类型判断 之前没有FETCH语句之前 bool值为空
%ISOPEN 当游标打开时为true
%ROWCOUNT 表示已经从游标中取出的数据的个数
带参数的游标的写法:
DECLARE CURSOR cur_para(id varchar2) IS --参数不需要添加长度 不用写varchar2(10) SELECT book_name FROM books WHERE book_id=id; t_name books.book_name%TYPE; --定义变量t_name指定t_name为books.book_name类型和长度 BEGIN OPEAN cur_para('0001'); --传进参数0001 LOOP FETCH cur_para INTO t_name; EXIT WHEN cur_para%NOTFOUND; DBMS_OUTPUT.PUT_LINE(t_name); END LOOP; END; /
DECLARE t_name varchar2(); CURSOR mycur IS SELECT name FROM deptment; BEGIN OPEN mysur; LOOP FETCH mycur INTO t_name; EXIT WHEN mycur%NOTFOUND OR mycur%NOTFOUND IS NULL; DBMS_OUTPUT.PUT_LINE('游标mycur ROWCOUNT:'||mycur%ROWCOUNT); END LOOP; CLOSE mycur; END; /
利用游标修改数据:
在用游标修改表时 如修改student表 必须是SELECT * FROM student FOR UPDATE;FOR UPDATE 相当于解开修改数据的小锁头。
DECLARE CURSOR cur IS SELECT name FROM deptment FOR UPDATE; text varchar2(10); BEGIN OPEN cur; FETCH cur INTO text; --将游标中的数据取出放入text WHILE cur%FOUND LOOP UPDATE deptment SET name=name||'_t' WHERE CURRENT OF cur; --判断游标当前行 修改当前行数据 FETCH cur INTO text; END LOOP; CLOSE cur; END; /
隐式游标:
没有游标的声明,打开,关闭的语句
BEGIN FOR cur IN(SELECT name FROM deptmenet) LOOP DBMS_OUTPUT.PUT_LINE(cur.name); END LOOP; END; /
注意:
当数据库中数据量较大时,不适合使用游标,因为一条一条的取,效率比较多的低。