2015-07-20 92 views
0

未经测试的水域,我试图找到一种方法来缓解事情。而不是在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 [email protected]_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 [email protected]_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 [email protected]_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

ao_in是对过程的参数。它也是桌子上的一列吗?因为如果不是,我不会看不到你想要做什么的逻辑。 – Rene

+2

你不能使用'case'来运行不同的语句。 (SQL)情况只能用于返回单个(列)值。你需要三个光标,然后当你打开光标时,你需要检查参数并打开正确的参数。 –

+0

@ahorsewithnoname联盟所有和检查参数值的条件是什么?-) –

回答

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 [email protected]_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 [email protected]_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 [email protected]_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是在原始代码的某个地方声明的,为了简化不在这里发布,否则应该声明。

0

我们来分析一下你的选择:无论案件表达的

SELECT t1.nr, t1.status$nr 
    FROM [email protected]_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和union使用where条件来处理所有这些select语句。

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 [email protected]_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! * {:-)

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; 

出认沽:

anonymous block completed 
for id = 1 
0011 
0012 
0013 
0014 
for id = 2 
0015 
0016 
0017