转自http://www.itpub.net/thread-2084177-1-1.html 感谢newkid
原始出处: http://www.plsqlchallenge.com/ 作者:Steven Feuerstein 运行环境:SQLPLUS, SERVEROUTPUT已打开 我创建了如下的表并且填充了数据: CREATE TABLE plch_parts ( partnum INTEGER PRIMARY KEY , partname VARCHAR2 (100) UNIQUE ) / BEGIN INSERT INTO plch_parts VALUES (1, 'Mouse'); INSERT INTO plch_parts VALUES (100, 'Keyboard'); INSERT INTO plch_parts VALUES (500, 'Monitor'); COMMIT; END; / 哪些代码块执行之后会显示如下输出: 1 500 注意:每个选项都有一模一样的如下执行代码: LOOP FETCH parts_cur INTO l_part; EXIT WHEN parts_cur%NOTFOUND; sys.DBMS_OUTPUT.put_line (l_part.partnum); END LOOP; CLOSE parts_cur; END; / 你可以专注于每个选项的声明部分和游标打开方式。 (A) DECLARE l_filter VARCHAR2 (100) := 'M%'; CURSOR parts_cur IS SELECT * FROM plch_parts WHERE partname LIKE l_filter ORDER BY partnum; l_part plch_parts%ROWTYPE; BEGIN OPEN parts_cur; LOOP FETCH parts_cur INTO l_part; EXIT WHEN parts_cur%NOTFOUND; sys.DBMS_OUTPUT.put_line (l_part.partnum); END LOOP; CLOSE parts_cur; END; / (B) DECLARE CURSOR parts_cur (filter_in IN VARCHAR2) IS SELECT * FROM plch_parts WHERE partname LIKE filter_in ORDER BY partnum; l_part plch_parts%ROWTYPE; BEGIN OPEN parts_cur ('M%'); LOOP FETCH parts_cur INTO l_part; EXIT WHEN parts_cur%NOTFOUND; sys.DBMS_OUTPUT.put_line (l_part.partnum); END LOOP; CLOSE parts_cur; END; / (C) DECLARE l_filter VARCHAR2 (100); CURSOR parts_cur (filter_in IN VARCHAR2) IS SELECT * FROM plch_parts WHERE partname LIKE l_filter ORDER BY partnum; l_part plch_parts%ROWTYPE; BEGIN OPEN parts_cur ('M%'); LOOP FETCH parts_cur INTO l_part; EXIT WHEN parts_cur%NOTFOUND; sys.DBMS_OUTPUT.put_line (l_part.partnum); END LOOP; CLOSE parts_cur; END; / (D) DECLARE CURSOR parts_cur (filter_in IN VARCHAR2 DEFAULT 'M%') IS SELECT * FROM plch_parts WHERE partname LIKE filter_in ORDER BY partnum; l_part plch_parts%ROWTYPE; BEGIN OPEN parts_cur (); LOOP FETCH parts_cur INTO l_part; EXIT WHEN parts_cur%NOTFOUND; sys.DBMS_OUTPUT.put_line (l_part.partnum); END LOOP; CLOSE parts_cur; END; / (E) DECLARE l_filter VARCHAR2 (100) := 'M%'; CURSOR parts_cur (filter_in IN OUT VARCHAR2) IS SELECT * FROM plch_parts WHERE partname LIKE filter_in ORDER BY partnum; l_part plch_parts%ROWTYPE; BEGIN OPEN parts_cur (l_filter); LOOP FETCH parts_cur INTO l_part; EXIT WHEN parts_cur%NOTFOUND; sys.DBMS_OUTPUT.put_line (l_part.partnum); END LOOP; CLOSE parts_cur; END; / (F) DECLARE l_filter VARCHAR2 (100) := 'M%'; CURSOR parts_cur (filter_in OUT VARCHAR2) IS SELECT * FROM plch_parts WHERE partname LIKE filter_in ORDER BY partnum; l_part plch_parts%ROWTYPE; BEGIN OPEN parts_cur (l_filter); LOOP FETCH parts_cur INTO l_part; sys.DBMS_OUTPUT.put_line (l_part.partnum); EXIT WHEN parts_cur%NOTFOUND; END LOOP; CLOSE parts_cur; END; /
A: 这个选项用了一个局部变量,在游标内部直接引用,来得到所需的结果。这不是写这类代码的最佳方法,因为该游标对声明于更高作用域内的变量有着某种“全局”的依赖。更好的方法是为游标定义一个参数,并且将l_filter传递给游标,如下: OPEN parts_cur (l_filter); B: 这个选项用了一个参数化的游标来传递过滤条件。 C: 这个选项用了一个参数化的游标,但是参数从未被使用!相反,游标仍然在WHERE子句中引用l_filter,它从未被赋予一个值。代码能够编译执行不出错,但是不会显示任何结果。 D: 游标的参数有一个缺省值,就像程序参数那样,你可以打开游标而无需为那个参数传递一个值,Oracle会使用缺省值。 E: 这个选项指定了IN OUT作为参数模式。Oracle文档只显示了IN模式的使用,但是Oracle并不会抱怨IN OUT,而它当然也不会修改变量的值。 F: 这个选项将游标参数模式指定为OUT。Oracle在文档中没有允许这种做法,但是实际上它不会报编译错误。然而,既然模式是OUT,在游标中看不到这个变量的值,所以它找不到任何数据,也没有输出。
没什么好说的,没用过游标的可以百度用法。