从游标复制获取

时间:2012-03-01 08:42:42

标签: plsql oracle10g

假设我有一个带有主键conf的表PK

Conf
------------------
PK  A    B     C
------------------
1   Y    Y     Y
2   Y          Y
3   Y    
------------------

我有另一个表temp:

Temp
------------------
PK  A    B     C
------------------
1   ab   cd    ef
1   null cd    ef
2   cd         pq
3   dn    
------------------

我需要从conf表中获取值Y的列和PK的所有名称,例如:

1  A  B  C
2  A  C
3  A

需要将这些值与temp表行进行比较,并检查该列中fetched的值是否为null,如果是,则抛出错误。

例如,对于2 A C,我们需要将2作为PK的临时表的A和C列进行比较。

我的问题是如何在光标中获取以下记录:

1  A  B  C
2  A  C
3  A

我没有得到优化的解决方案。可以通过将conf表的所有列与temp表进行比较来完成,但可以有超过15列。

算法的大纲是:

fetch all column name from conf table having value 'Y'
loop
    fetch all the columns from temp table with primary key from outer cursor
    loop
        On the basis of column name from outer cursor check the value of column
        of temp table for its nullability 
    end loop;
end loop;

1 个答案:

答案 0 :(得分:2)

我认为使用类似的查询更好:

select c.*, t.*
  from conf c, temp t
 where c.pk = t.pk
   and ((c.a = 'Y' and t.a is null) or (c.b = 'Y' and t.b is null) or
       (c.c = 'Y' and t.c is null))

如果您不知道列,可以通过循环user_tab_cols / all_tab_cols来动态创建查询:

declare

  sql_str varchar2(32767);

  cursor c_col is
    select tc.column_name
      from user_tab_cols tc
     where tc.table_name = 'CONF' and tc.column_name <> 'PK';

  type rc_bad_rows is ref cursor;
  c_bad_rows rc_bad_rows;

  val number;

  is_first boolean := true;

begin

  sql_str := 'select t.pk from conf c, temp t ' ||
             'where c.pk = t.pk and (';

  for r in c_col loop

    if not is_first then
      sql_str := sql_str || ' or ';
    end if;

    is_first := false;

    sql_str := sql_str || '(c.' || r.column_name || ' = ''Y'' and t.' ||
               r.column_name || ' is null)';

  end loop;

  sql_str := sql_str || ')';

  dbms_output.put_line(sql_str);

  open c_bad_rows for sql_str;

  loop
    fetch c_bad_rows
      into val;
    exit when c_bad_rows%notfound;
    dbms_output.put_line(val);
  end loop;

  close c_bad_rows;
end;

这段代码可能不是最好的,但它就是一个例子......