Oracle 游标Select语句,其中条件根据条件更改
我在一个过程中使用游标,这里我不使用批量收集,因为我对从游标获取的记录进行了大量计算 在Cursor的Select语句Where子句根据条件更改时,我尝试使用以下代码,但它给了我错误: 错误(19,12):PLS-00103:在预期以下情况之一时遇到符号“c_recs”:=。(@%Oracle 游标Select语句,其中条件根据条件更改,oracle,select,cursor,conditional-statements,Oracle,Select,Cursor,Conditional Statements,我在一个过程中使用游标,这里我不使用批量收集,因为我对从游标获取的记录进行了大量计算 在Cursor的Select语句Where子句根据条件更改时,我尝试使用以下代码,但它给了我错误: 错误(19,12):PLS-00103:在预期以下情况之一时遇到符号“c_recs”:=。(@% 我不想使用SYS_REFCURSOR,因为从网络上看,我读到的游标比ref游标稍微好一些。游标声明中的CASE解决了这个问题: DECLARE CURSOR c_recs IS SELECT
我不想使用SYS_REFCURSOR,因为从网络上看,我读到的游标比ref游标稍微好一些。
游标声明中的CASE
解决了这个问题:
DECLARE
CURSOR c_recs
IS
SELECT cname
FROM a_aud aa
WHERE aa.time BETWEEN TO_DATE (fromdate_in, 'dd/mm/rrrr')
AND TO_DATE (todate_in, 'dd/mm/rrrr')
AND aa.ctype =
CASE
WHEN atype_in = '01' THEN 'RAlert'
WHEN atype_in = '02' THEN 'DAlert'
END;
BEGIN
FOR rec IN c_recs
LOOP
NULL;
END LOOP;
END;
我无法评论您的refcursor语句。
游标声明中的CASE
解决了该问题:
DECLARE
CURSOR c_recs
IS
SELECT cname
FROM a_aud aa
WHERE aa.time BETWEEN TO_DATE (fromdate_in, 'dd/mm/rrrr')
AND TO_DATE (todate_in, 'dd/mm/rrrr')
AND aa.ctype =
CASE
WHEN atype_in = '01' THEN 'RAlert'
WHEN atype_in = '02' THEN 'DAlert'
END;
BEGIN
FOR rec IN c_recs
LOOP
NULL;
END LOOP;
END;
我无法对您的refcursor语句进行评论。更好、更有效的方法是在一条语句中执行此操作,而不使用任何游标。但是,这取决于您要执行的操作。如果必须基于游标记录执行DML,最好在一条语句中执行 如果确实希望在循环中处理某些内容,请使用与显式游标等效(有时性能更好)的隐式游标循环 还可以使用条件逻辑而不是IF/ELSE简化select查询
CREATE OR REPLACE PROCEDURE "test" (
fromdate_in IN VARCHAR2,
todate_in IN VARCHAR2,
atype_in
in NUMBER
) is begin
for cur in (
SELECT cname
FROM a_aud aa
WHERE aa.time BETWEEN TO_DATE(fromdate_in,'dd/mm/rrrr')
AND TO_DATE(todate_in,'dd/mm/rrrr') AND (
(
atype_in = '01' AND aa.ctype = 'RAlert'
) OR (
atype_in = '02' AND aa.ctype = 'DAlert'
)
)
) loop
---calculations
do_something_with(cur.cname)
end loop;
end;
/
我还建议您将参数类型设置为日期,并直接从调用块传递变量,而不是在sql/cursor中进行转换。这将避免
到日期的转换。一个更好、更有效的选择是在单个语句中进行转换,而不使用任何游标。但是,这取决于如果必须基于游标记录执行DML,最好在单个语句中执行
如果确实希望在循环中处理某些内容,请使用与显式游标等效(有时性能更好)的隐式游标循环
还可以使用条件逻辑而不是IF/ELSE简化select查询
CREATE OR REPLACE PROCEDURE "test" (
fromdate_in IN VARCHAR2,
todate_in IN VARCHAR2,
atype_in
in NUMBER
) is begin
for cur in (
SELECT cname
FROM a_aud aa
WHERE aa.time BETWEEN TO_DATE(fromdate_in,'dd/mm/rrrr')
AND TO_DATE(todate_in,'dd/mm/rrrr') AND (
(
atype_in = '01' AND aa.ctype = 'RAlert'
) OR (
atype_in = '02' AND aa.ctype = 'DAlert'
)
)
) loop
---calculations
do_something_with(cur.cname)
end loop;
end;
/
我还建议您将参数类型作为日期,并直接从调用块传递变量,而不是在sql/游标中转换。这将避免到日期的转换。谢谢Nayak,我使用了这个解决方案谢谢Nayak,我使用了这个解决方案谢谢Littlefoot,答案是有用的谢谢Littlefoot,一个斯韦尔很有用