如何使用PL / SQL更改您在FOR循环IN子句中查询的表

时间:2018-02-28 19:21:07

标签: sql oracle for-loop plsql

我正在尝试使用pl / sql脚本来检查每列的每个值以及每行的尾随空格。

我的计划是从dba_tab_cols获取我的应用程序的列和表名,然后遍历该列上该表的每一行,并检查尾随空格和修剪(如果需要)。

我的问题是,这需要我的内部循环必须更新它正在选择的表,并且发现不支持这样的操作。我不确定是否有办法绕过这个或另一个我应该考虑的方法。我探索的每条路径都会遇到同样的问题:我必须更新内循环选择的表。

我的伪代码如下:

BEGIN
  for i in
    (
    --get table name and column name for all tables from MYAPP
    select table_name, column_name from dba_tab_cols where owner='MYAPP'
    )
    LOOP
      BEGIN
        for k in
          (
          -- for each column in each table returned from outer loop, loop through each row and check for trailing whitespace
          select i.column_name from MYAPP.i.table_name -- I know this is wrong, not sure what should go here
          )
          LOOP
            -- compare value of column with value of trim(column) 
            -- if different then fix
          END LOOP;
      END;
    END LOOP;
END;
/

编辑:一个要求是识别并打印出有问题的值,因此简单的更新语句是不够的。我一直在尝试理解sys_refcursor,因为看起来这可能就是我需要的东西,但我正在努力去掌握它。

2 个答案:

答案 0 :(得分:1)

如果无法在代码中编写特定的表名,则需要动态SQL语句。

BEGIN
  for i in
    (
    --get table name and column name for all tables from MYAPP
    select table_name, column_name, owner from dba_tab_cols where owner='MYAPP'
    )
    LOOP
      execute immediate 'update ' || i.owner || '.' || i.table_name 
        || ' set ' || i.column_name || ' = trim(' || i.column_name || ') '
        || ' where ' || i.column_name || ' <> trim(' || i.column_name || ')';
    END LOOP;
END;
/

编辑:好的,如果你想记录它找到的每个值,那就更复杂了,哈哈!是的,非常确定你需要第二个循环。有几种方法可以做这种事情;我在一个集合中进行了批量收集,然后循环遍历该集合。

DECLARE
  type t_srec is RECORD(rid ROWID, str varchar2(4000));
  type t_string_tab is table of t_srec;
  v_st t_string_tab;
BEGIN
  for i in
    (
    --get table name and column name for all tables from MYAPP
    select table_name, column_name, owner from dba_tab_cols where owner='MYAPP'
    )
    LOOP
      execute immediate 'select rowid, ' || i.column_name || ' as str from ' || i.table_name 
        || ' where ' || i.column_name || ' <> trim(' || i.column_name || ')'
        bulk collect into v_st;
      for j in 1..v_st.count loop
        dbms_output.put_line(i.table_name || '.' || i.column_name || ' has value: ' || v_st(j).str);
        execute immediate 'update ' || i.table_name 
            || ' set ' || i.column_name || ' = trim(' || i.column_name || ') '
            || ' where rowid = :rid' using v_st(j).rid;
      end loop;
    END LOOP;
END;
/

答案 1 :(得分:0)

请参阅:Search All Fields In All Tables For A Specific Value (Oracle)

您必须弄清楚如何检查空白区域,但您之前已解决了大部分问题。