我的情况是我的oracle
db有大约20个表,都有一个名为 itemId 的索引字段。
我想从所有20个表中复制带有id(称为101)的记录,并使用新的id(称为102)插入它们。
我不希望有20个游标或20 functions/procedures
,因为表格列表可能会在未来增长。帮助我以更好的方式实现这一目标。
答案 0 :(得分:0)
由于您有可能可变数量的表,您将需要使用动态SQL来实现您的目标。以下内容应该有所帮助:
DECLARE
l_insert_column_list VARCHAR2(4000);
l_select_column_list VARCHAR2(4000);
BEGIN
FOR table_rec IN (SELECT table_name
FROM user_tab_columns
WHERE UPPER(column_name) = 'ITEMID')
LOOP
l_insert_column_list := '';
l_select_column_list := '';
FOR col_rec IN (SELECT column_name
FROM user_tab_columns
WHERE table_name = table_rec.table_name)
LOOP
l_insert_column_list := l_insert_column_list || col_rec.column_name || ',';
IF UPPER(col_rec.column_name) = 'ITEMID' THEN
l_select_column_list := l_select_column_list || '102,';
ELSE
l_select_column_list := l_select_column_list || col_rec.column_name || ',';
END IF;
END LOOP;
l_insert_column_list := RTRIM(l_insert_column_list, ',');
l_select_column_list := RTRIM(l_select_column_list, ',');
EXECUTE IMMEDIATE 'INSERT INTO ' || table_rec.table_name || ' ('
|| l_insert_column_list || ') SELECT ' || l_select_column_list ||
' FROM ' || table_rec.table_name || ' WHERE ITEMID = 101';
END LOOP;
END;
/
这里的想法是使用user_tab_columns
数据字典视图列出所有具有ITEMID
列的表。对于每个这样的表,我们然后使用user_tab_columns
列出表中的所有列,然后构建一个SQL字符串来复制数据。
我在这里做了一些假设:
您的所有表都在同一架构中。如果没有,您可能需要使用all_tab_columns
而不是user_tab_columns
,并将架构所有者包含在table_rec
和SQL字符串中,其中table_rec.table_name
也会使用。
您的表名或列名都不具有需要用双引号括起来的名称。 (如果有,则必须调整SQL字符串以包含双引号。)
表格中的所有列名称都有4000个字符。 (由于列名限制为30个字符,因此需要超过100列才能触发此问题。)
在您的数据库中放弃此脚本之前,我强烈建议您通过调用EXECUTE IMMEDIATE
替换dbms_output.put_line
,以便可以看到正在生成的SQL字符串。