未经考验的水域,我试图找到一种方法来缓解问题。而不是在PL-SQL中的游标中嵌套选择。我试图在光标中创建一个案例。由于光标可以有不同的参数,我需要相应地对事物进行排序。
这可能吗?我的代码看起来像这样。它很容易阅读ao_in是Inparam。
PROCEDURE theProcedure (ao_in IN VARCHAR2)
CURSOR order_cur
IS
Case when ao_in = 'NIEC'
then
SELECT t1.nr, t1.status$nr
FROM eh_order_t@NGEXT_DBLINK t1
WHERE t1.status$nr IN (3, 6)
AND ao_in =
DECODE (ao_in, 'NIEC', ao_in, get_ehorder_ao (t1.nr))
AND t1.nr = DECODE (order_in, NULL, t1.nr, order_in)
ORDER BY t1.skapad_dat ASC;
when ao_in = 'DSSP' then
SELECT t1.nr, t1.status$nr
FROM eh_order_t@NGEXT_DBLINK t1
WHERE t1.status$nr IN (3, 6)
AND ao_in =
DECODE (ao_in, 'DSSP', ao_in, get_ehorder_ao (t1.nr))
AND t1.nr = DECODE (order_in, NULL, t1.nr, order_in)
ORDER BY t1.skapad_dat ASC;
when ao_in = 'ALLA'
SELECT t1.nr, t1.status$nr
FROM eh_order_t@NGEXT_DBLINK t1
WHERE t1.status$nr IN (3, 6)
AND ao_in =
DECODE (ao_in, 'ALLA', ao_in, get_ehorder_ao (t1.nr))
AND t1.nr = DECODE (order_in, NULL, t1.nr, order_in)
ORDER BY t1.skapad_dat ASC;
end
答案 0 :(得分:1)
您可以使用OPEN-FOR语句完成所需的操作,如下所示:
PROCEDURE theProcedure (ao_in IN VARCHAR2)
TYPE t_cur IS REF CURSOR;
order_cur t_cur;
begin
Case when ao_in = 'NIEC'
then
open order_cur for
SELECT t1.nr, t1.status$nr
FROM eh_order_t@NGEXT_DBLINK t1
WHERE t1.status$nr IN (3, 6)
AND ao_in = 'NIEC'
AND t1.nr = DECODE (order_in, NULL, t1.nr, order_in)
ORDER BY t1.skapad_dat ASC;
when ao_in = 'DSSP' then
open order_cur for
SELECT t1.nr, t1.status$nr
FROM eh_order_t@NGEXT_DBLINK t1
WHERE t1.status$nr IN (3, 6)
AND ao_in = 'DSSP'
AND t1.nr = DECODE (order_in, NULL, t1.nr, order_in)
ORDER BY t1.skapad_dat ASC;
when ao_in = 'ALLA'
open order_cur for
SELECT t1.nr, t1.status$nr
FROM eh_order_t@NGEXT_DBLINK t1
WHERE t1.status$nr IN (3, 6)
AND ao_in ='ALLA'
AND t1.nr = DECODE (order_in, NULL, t1.nr, order_in)
ORDER BY t1.skapad_dat ASC;
end;
end;
请注意,ao_in参数的解码评估不是必需的,因为已在case语句中对其进行了评估。 我假设order_in在原始代码中的某处声明,并且为了简化而未在此处发布,否则应该声明它。
答案 1 :(得分:1)
假设你的eh_order_t @ngext_dblink表中有一个名为“ao_in”的列,我认为你所追求的是这样的:
PROCEDURE theProcedure (p_ao_in IN VARCHAR2)
IS
CURSOR order_cur
IS
SELECT t1.nr,
t1.status$nr
FROM eh_order_t@NGEXT_DBLINK t1
WHERE t1.status$nr IN (3, 6)
AND (p_ao_in in ('NIEC', 'DSSP', 'ALLA')
OR
(p_ao_in not in ('NIEC', 'DSSP', 'ALLA') and ao_in = get_ehorder_ao (t1.nr)))
AND t1.nr = COALESCE(order_in, t1.nr)
ORDER BY t1.skapad_dat ASC;
BEGIN
FOR order_rec in order_cur
LOOP
-- do the things
END LOOP;
END;
/
或者,你可以有两个游标,一个选择所有内容,一个过滤ao_in列,然后根据传入的参数调用相关的游标。我相信Oracle应该能够优化上面的基于传入的参数组合游标,但是如果你发现它不能或不想确定,将游标分成两个单独的游标将有助于优化器。
重要的是,您不应在PL / SQL中的游标中使用相同的参数或变量名称,因为优化程序可能会非常混淆,并且很可能会使您的and column_name = variable_of_same_name_as_column_name
变为平均值and column_name = column_name
,这可能不是你想要的!
ETA:如果在循环中完成的工作是DML,那么您可能可以完全取消游标并且只有一个DML语句。这将是最好的使用方案,因为逐行处理不是PL / SQL中最快的事情。基于集合的处理ftw! * {: - )
答案 2 :(得分:0)
让我们分析您的选择:
SELECT t1.nr, t1.status$nr
FROM eh_order_t@NGEXT_DBLINK t1
WHERE t1.status$nr IN (3, 6)
AND ao_in =
DECODE (ao_in, 'DSSP', ao_in, get_ehorder_ao (t1.nr))
AND t1.nr = DECODE (order_in, NULL, t1.nr, order_in)
ORDER BY t1.skapad_dat ASC;
无论案例表达如何,条件ao_in = DECODE...
始终为真
条件t1.nr = DECODE...
可以重写为t1.nr = NVL(order_in, t1.nr)
,但order_in
的定义在哪里?
结合:你的情况没有任何意义(并且不能以这种方式制作)。
如果要根据参数运行不同的select语句,请使用where条件并联合所有这些select语句。
答案 3 :(得分:0)
您可以使用参数光标link
例如:
CREATE TABLE tbl
(ID int, name varchar(50));
INSERT INTO tbl select 1, '0011' from dual;
INSERT INTO tbl select 1, '0012' from dual;
INSERT INTO tbl select 1, '0013' from dual;
INSERT INTO tbl select 1, '0014' from dual;
INSERT INTO tbl select 2, '0015' from dual;
INSERT INTO tbl select 2, '0016' from dual;
INSERT INTO tbl select 2, '0017' from dual;
set serveroutput on
declare
CURSOR para_cur(num NUMBER) IS select name from tbl where id = num;
begin
dbms_output.put_line('for id = 1');
FOR idx in para_cur(1) LOOP
dbms_output.put_line(idx.name);
end loop;
dbms_output.put_line('for id = 2');
FOR idx in para_cur(2) LOOP
dbms_output.put_line(idx.name);
end loop;
end;
out Put:
anonymous block completed
for id = 1
0011
0012
0013
0014
for id = 2
0015
0016
0017