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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用PL / SQL更改您在FOR循环IN子句中查询的表相关的知识,希望对你有一定的参考价值。

我正在尝试拧一个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,因为它似乎可能就是我需要的东西,但是我正在努力去理解它。

答案

如果无法在代码中编写特定的表名,则需要动态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;
/
另一答案

见:Search All Fields In All Tables For A Specific Value (Oracle)

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

以上是关于如何使用PL / SQL更改您在FOR循环IN子句中查询的表的主要内容,如果未能解决你的问题,请参考以下文章

如何转换逗号分隔的 varchar 以用于 pl/sql 中的“IN”子句?

PL/SQL - 在 Where In 子句中使用“列表”变量

如何在选择语句的“NOT IN”子句中使用逗号分隔的字符串列表作为 pl/sql 存储的函数参数

pl sql cursor for loop in

将 IN() 用于数组的 PL/SQL where 子句

pl / sql如何使用带有游标的for循环进行更新操作