如何使用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 子句中使用“列表”变量