我想浏览所有表并将ID和tablename复制到表中.因为我必须使用变量作为表名,所以我尝试使用IMMEDIATE EXECUTE.但是对于动态SQL,INSERT INTO语句只允许单行.
如果 IMMEDIATE EXECUTE允许INSERT INTO使用muplitple行,则可以使用以下SQL语句.
DECLARE
sqlStat VARCHAR2(500);
BEGIN
FOR TName IN (
SELECT TABLE_NAME FROM all_tab_cols WHERE column_name='ID'
)
LOOP
sqlStat := 'INSERT INTO storeTab (ID,TABLE_NAME) SELECT ID, '' :1 '' FROM :2';
EXECUTE IMMEDIATE sqlStat USING TName.TABLE_NAME,TName.TABLE_NAME;
END LOOP;
END;
Run Code Online (Sandbox Code Playgroud)
如何循环表和收集记录?
一个insert ... select如果它是通过"普通" SQL执行时,通过PL/SQL或通过动态SQL可以插入多个行,而不管.
但是,您不能在动态SQL中使用占位符作为标识符(名称).您需要连接查询.如果要通过USING子句传递值,则不需要使用单引号:
DECLARE
sqlStat VARCHAR2(500);
BEGIN
FOR TName IN (SELECT TABLE_NAME FROM all_tab_cols WHERE column_name='ID' and table_name = 'FOO')
LOOP
sqlStat := 'INSERT INTO storetab (ID,TABLE_NAME) SELECT ID, :1 FROM '||tname.table_name;
EXECUTE IMMEDIATE sqlStat USING TName.TABLE_NAME;
END LOOP;
END;
/
Run Code Online (Sandbox Code Playgroud)
这将插入storetab与源表中的行一样多的行.
有点无关,但是:
all_tab_columns如果当前用户可以访问不同模式中的那些表,则可能会多次返回相同的表名.如果您只对当前用户拥有的表感兴趣,则应该选择ownerfrom all_tab_columns and adjust theselect part of the dynamic SQL accordingly. Or useuser_tab_cols`来正确处理.