【DM】DMSQL 程序的基本操作,下载量瞬秒百万
50 局部
DMSQL 过程已成功完成
已用时间: 0.730(毫秒). 执行号:1835.
从结果可以看出,两个 X 的作用域是完全不同的。
===================================================================
只读,编译时就能确定使用的查询。
隐式
无需用户隐式定义,每当用户执行 DML 操作,DMSQL 都会自动声明一个隐式游标并对其进行管理。隐式游标的名称为”SQL“,它有 %FOUND、%NOTFOUND、%ISOPEN 和 %ROWCOUNT 这四个属性。属性意义如下:
%FOUND:语句是否修改或查询到了记录。
%NOTFOUND:语句是否为呢个成功修改或查询到记录。
%ISOPEN:游标是否打开。隐式游标永远为未打开状态。
%ROWCOUNT:DML 语句影响的行数。
实例
建表
DROP TABLE IF EXISTS TEST;
CREATE TABLE TEST(
C1 INT,
C2 VARCHAR(50)
);
程序
BEGIN
UPDATE TEST SET C2 = '韩梅梅' WHERE C1=1;
IF SQL%NOTFOUND THEN
PRINT '查无此人';
ELSE
PRINT '修改成功';
END IF;
END;
结果
SQL> BEGIN
2 UPDATE TEST SET C2 = '韩梅梅' WHERE C1=1;
3 IF SQL%NOTFOUND THEN
4 PRINT '查无此人';
5 ELSE
6 PRINT '修改成功';
7 END IF;
8 END;
9 /
查无此人
DMSQL 过程已成功完成
已用时间: 0.712(毫秒). 执行号:1745.
显式
显式游标指向一个查询语句执行后的结果集区域。当需要处理返回多条记录的查询时,应显式地定义游标以处理结果集的每一行。
使用显式游标的步骤:
定义:声明游标及其关联查询语句。
打开:执行。将查询结果装入工作区,游标被定位到结果集的第一行之前。
拨动:根据需要将游标位置移动到结果集的合适位置。
关闭:使用完游标后关闭,释放其占用的资源。
实例
插入测试数据
INSERT INTO TEST VALUES(1,'韩梅梅'),(2,'李华');
程序
DECLARE
A INT;
B VARCHAR(50);
CURSOR C FOR SELECT * FROM TEST; --定义游标
BEGIN
OPEN C ; --打开游标
LOOP
FETCH C INTO A,B; --拨动游标
EXIT WHEN C%NOTFOUND;
PRINT A||'--'||B;
END LOOP;
CLOSE C; --关闭游标
END;
结果
SQL> DECLARE
2 A INT;
3 B VARCHAR(50);
4 CURSOR C FOR SELECT * FROM TEST;
5 BEGIN
6 OPEN C ;
7 LOOP
8 FETCH C INTO A,B;
9 EXIT WHEN C%NOTFOUND;
10 PRINT A||'--'||B;
11 END LOOP;
12 CLOSE C;
13 END;
14 /
1--韩梅梅
2--李华
DMSQL 过程已成功完成
已用时间: 0.234(毫秒). 执行号:1794.
与静态游标不同,动态游标在声明部分只是先声明一个游标类型的变量,并不指定其关联的查询语句,在执行部分打开游标时才指定查询语句。
实例
程序
DECLARE
A INT;
B VARCHAR(50);
C CURSOR; --声明游标
BEGIN
OPEN C FOR SELECT * FROM TEST; --定义并打开游标
LOOP
FETCH C INTO A,B; --拨动游标
EXIT WHEN C%NOTFOUND;
PRINT A||'--'||B;
END LOOP;
CLOSE C; --关闭游标
END;
结果
SQL> DECLARE
2 A INT;
3 B VARCHAR(50);
4 C CURSOR;
5 BEGIN
6 OPEN C FOR SELECT * FROM TEST;
7 LOOP
8 FETCH C INTO A,B;
9 EXIT WHEN C%NOTFOUND;
10 PRINT A||'--'||B;
11 END LOOP;
12 CLOSE C;
13 END;
14 /
1--韩梅梅
2--李华
DMSQL 过程已成功完成
已用时间: 0.350(毫秒). 执行号:1795.
游标变量不是真正的游标对象,而是指向游标对象的一个指针,因此是一种引用类型,也可以成为引用游标。
引用游标的特点:
不局限于一个查询
可以被赋值
可以作为变量使用
可以在 DMSQL 的子程序中传递结果集
实例
将 TEST2 表中的数据合并到 TEST 表中
建测试数据
DROP TABLE IF EXISTS TEST2;
CREATE TABLE TEST2(C1 INT,C2 VARCHAR(50));
INSERT INTO TEST2 VALUES(5,'刘磊'),(6,'叶枫');
程序
DECLARE
CSR CURSOR; --声明游标
PROCEDURE PROC(CSR IN CURSOR) IS --定义存储过程
PERSON TEST%ROWTYPE; --定义结果集
/子程序开始/
BEGIN
LOOP
FETCH CSR INTO PERSON; --拨动游标,将数据放入结果集
EXIT WHEN CSR%NOTFOUND;
INSERT INTO TEST
VALUES(PERSON.C1,PERSON.C2);--将结果集中的数据插入到 TEST 表中
COMMIT;
END LOOP;
END;
/子程序结束/
BEGIN
OPEN CSR FOR SELECT * FROM TEST2; --对游标进行定义
PROC(CSR); --存储过程调用游标
CLOSE CSR; --关闭游标
END;
结果
SQL> DECLARE
2 CSR CURSOR; --声明游标
3 PROCEDURE PROC(CSR IN CURSOR) IS --定义存储过程
4 PERSON TEST%ROWTYPE; --定义结果集
5 /子程序开始/
6 BEGIN
7 LOOP
8 FETCH CSR INTO PERSON; --拨动游标,将数据放入结果集
9 EXIT WHEN CSR%NOTFOUND;
10
11 VALUES(PERSON.C1,PERSON.C2);--将结果集中的数据插入到 TEST 表中
12 END LOOP;
13 END;
14 /子程序结束/
15 BEGIN
16 OPEN CSR FOR SELECT * FROM TEST2; --对游标进行定义
17 PROC(CSR); --存储过程调用游标
18 CLOSE CSR; --关闭游标
19 END;
20 /
DMSQL 过程已成功完成
已用时间: 0.303(毫秒). 执行号:1912.
SQL> SELECT * FROM TEST;
行号 C1 C2
1 3 韩梅梅
2 2 李华
3 5 刘磊
4 6 叶枫
已用时间: 6.982(毫秒). 执行号:1913.
使用游标进行数据的更新或删除时,关联的查询语句中一定要使用”FOR UPDATE“选项,它的意义在于对要修改的行上锁,以防用户在同一行上进行修改操作。
实例——更新
程序
将 TEST 表中 C1=1 的行的 C1 字段改为 3
DECLARE
CURSOR CSR IS SELECT C2 FROM TEST WHERE C1=1 --定义游标
FOR UPDATE; --加锁
BEGIN
OPEN CSR; --打开游标
IF CSR%ISOPEN THEN --判断游标是否被打开
FETCH CSR; --拨动游标
UPDATE TEST SET C1=3 WHERE CURRENT OF CSR; --数据更新
ELSE
PRINT 'CURSOR IS NOT OPENED';
END IF;
CLOSE CSR; --关闭游标
END;
结果
SQL> DECLARE
2 CSR CURSOR; --声明游标
3 PROCEDURE PROC(CSR IN CURSOR) IS --定义存储过程
4 PERSON TEST%ROWTYPE; --定义结果集
5 /子程序开始/
6 BEGIN
7 LOOP
8 FETCH CSR INTO PERSON; --拨动游标,将数据放入结果集
9 EXIT WHEN CSR%NOTFOUND;
10 INSERT INTO TEST
11 VALUES(PERSON.C1,PERSON.C2);--将结果集中的数据插入到 TEST 表中
12 END LOOP;
13 END;
14 /子程序结束/
15 BEGIN
16 OPEN CSR FOR SELECT * FROM TEST2; --对游标进行定义
17 PROC(CSR); --存储过程调用游标
18 CLOSE CSR; --关闭游标
19 END;
20 /
DMSQL 过程已成功完成
已用时间: 0.303(毫秒). 执行号:1912.
SQL> SELECT * FROM TEST;
行号 C1 C2
1 3 韩梅梅
2 2 李华
3 5 刘磊
4 6 叶枫
已用时间: 6.982(毫秒). 执行号:1913.
实例——FOR 循环
游标 FOR 循环自动使用 FOR 循环依次读取结果集中的数据。当 FOR 循环开始时,游标自动打开,故而不需要使用 OPEN 方法;每循环一次自动读取游标当前行的数据,故而不需要使用 FETCH;数据遍历完毕自动推出 FOR 循环时,游标自动关闭,故而不需要 CLOSE。
程序
BEGIN
FOR CSR IN (SELECT * FROM TEST)
LOOP
DBMS_OUTPUT.PUT_LINE(CSR.C1||'是'||CSR.C2||'同学');
END LOOP;
END;
结果
评论