我想浏览所有表并将ID和tablename复制到表中。 因为我必须使用变量作为表名,所以我尝试使用IMMEDIATE EXECUTE。但是对于动态SQL,INSERT INTO语句只允许单行。
以下SQL语句就是这样,如果 IMMEDIATE EXECUTE允许INSERT INTO使用muplitple行。
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;
如何循环访问表并收集记录?
答案 0 :(得分:5)
insert ... select
可以插入多行,无论是否通过" plain" 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;
/
此将在storetab
中插入尽可能多的行,因为源表中有行。
有点无关,但是:
如果当前用户可以访问不同模式中的那些表,则 all_tab_columns
可能会多次返回相同的表名。如果您只对当前用户对拥有的表感兴趣,请从owner
选择all_tab_columns and adjust the
user_tab_cols`中选择part of the dynamic SQL accordingly. Or use
来正确处理。
答案 1 :(得分:0)
我更喜欢使用USER_TAB_COLUMNS,因为不需要使用表名附加模式名称。如果我们使用ALL_TAB_COLS,那么最好使用OWNER。
您还可以使用USER_TAB_COLUMNS。
按如下方式构建查询DECLARE
sqlStat VARCHAR2(500);
BEGIN
FOR TName IN (SELECT TABLE_NAME FROM USER_TAB_COLUMNS WHERE column_name='ID')
LOOP
sqlstat := 'INSERT INTO storeTab (ID,TABLE_NAME) SELECT ID, ''' ||TName.TABLE_NAME|| ''' FROM '||Tname.TABLE_NAME ;
EXECUTE IMMEDIATE sqlStat ;
END LOOP;
END;
从ALL_TAB_COLS
获取时DECLARE
sqlStat VARCHAR2(500);
BEGIN
FOR TName IN (SELECT OWNER,TABLE_NAME FROM ALL_TAB_COLS WHERE column_name='ID')
LOOP
sqlStat := 'INSERT INTO storeTab (ID,TABLE_NAME) SELECT ID, ''' ||TName.TABLE_NAME|| ''' FROM '||Tname.OWNER||'.'||Tname.TABLE_NAME;
EXECUTE IMMEDIATE sqlStat ;
END LOOP ;
END ;