【发布时间】:2014-01-22 16:15:53
【问题描述】:
我有点困惑
在这样的函数/过程中是否可能?
CURSOR CR IS
SELECT
FROM
WHERE Y = X
稍后在正文中,将 X 值更改为 Z 或其他值,然后重新打开游标以获取 Y = Z 的行?
【问题讨论】:
我有点困惑
在这样的函数/过程中是否可能?
CURSOR CR IS
SELECT
FROM
WHERE Y = X
稍后在正文中,将 X 值更改为 Z 或其他值,然后重新打开游标以获取 Y = Z 的行?
【问题讨论】:
有几种方法可以在不使用动态 SQL 的情况下做到这一点。一种选择是使用参数化游标:
DECLARE
nSome_value NUMBER := 666;
CURSOR CR(parmSome_value NUMBER) IS
SELECT *
FROM SOME_TABLE
WHERE SOME_COLUMN = parmSome_value;
BEGIN
nSome_value := 123; -- change value of nSome_value
OPEN CR(nSome_value); -- pass nSome_value in as the value of the cursor parameter
-- Fetch from the cursor, do whatever
CLOSE CR;
END;
它仍然是静态 SQL,但是通过将参数传递给游标,可以增加游标的可重用性。
另一种选择是使用游标 FOR 循环,在循环的 SQL 中引用变量:
DECLARE
nSome_value NUMBER := 666;
BEGIN
nSome_value := 123; -- change value of nSome_value
FOR aRow IN (SELECT *
FROM SOME_TABLE
WHERE SOME_COLUMN = nSome_value)
BEGIN
-- Do something useful with the rows returned by the cursor
END LOOP;
END;
请注意,在这些情况下,您不会更改 SQL - 您只是更改查询中使用的变量或参数的值。这些方法的一个优点是,与动态生成的 SQL 不同,它们不易受到 SQL 注入攻击。
分享和享受。
【讨论】:
是的,试试这样的(快速输入,因此语法可能不准确)
sql VARCHAR2(255);
cur REF CURSOR;
val varchar2(100);
val := X;
sql := 'SELECT .. FROM .. WHERE Y = :val';
open cur for
sql
USING val;
close cur;
....
val := Z;
open cur for
sql
USING val;
【讨论】:
这也可以通过使用类似函数的子程序而不是使用光标来完成
将缩短代码:
创建或替换函数 getashish(dept varchar2) return emp3 as
emp5 emp3 := emp3();
str varchar2(300);
开始
str := 'selectemp1(e.last_name,l.city,e.salary) 从员工 e 加入部门 d
on e.department_id = d.department_id 加入位置 l on d.location_id=l.location_id where
d.department_name = :dept';
立即执行 str 批量收集到 emp5 使用部门;
返回 emp5; 结束;
在这里你必须创建一个对象,包括你想要的返回类型,然后创建该对象的表:
创建或替换类型 emp1 作为对象 (lname varchar2(10),city varchar2(10),sal number(10));
和
创建或替换 键入 emp3 作为 emp1 的表;
【讨论】: