oracle pl / sql如何复制多个表的数据

时间:2013-10-08 06:42:00

标签: oracle plsql

我的情况是我的oracle db有大约20个表,都有一个名为 itemId 的索引字段。 我想从所有20个表中复制带有id(称为101)的记录,并使用新的id(称为102)插入它们。 我不希望有20个游标或20 functions/procedures,因为表格列表可能会在未来增长。帮助我以更好的方式实现这一目标。

1 个答案:

答案 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字符串。