0

oracleデータベースに約20個のテーブルがあり、すべてにitemIdというインデックスフィールドがあるシナリオがあります。20 個のテーブルすべてから ID (101 と呼ばれる) を持つレコードをコピーし、それらを新しい ID (102 と呼ばれる) で挿入したいと考えています。functions/proceduresテーブルリストが将来大きくなる可能性があるため、カーソルを 20 個または 20 個にしたくありません。より良い方法でこれを達成するのを手伝ってください。

4

1 に答える 1

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_recSQL 文字列に含めて、 も使用する必要がある場合がありますtable_rec.table_name

  • テーブルまたは列の名前に、二重引用符で囲む必要がある名前がありません。(その場合は、SQL 文字列を調整して二重引用符を含める必要があります。)

  • テーブル内のすべての列名には 4000 文字で十分です。(列名は 30 文字に制限されているため、この問題を引き起こすには 100 を超える列が必要になります。)

このスクリプトをデータベースに解放する前に、生成されている SQL 文字列を確認できるようにEXECUTE IMMEDIATE、 への呼び出しに置き換えることを強くお勧めします。dbms_output.put_line

于 2013-10-08T08:48:11.453 に答える