2016-09-12 67 views
0

私はPostgreSQLのあるテーブルから別のテーブルにカラムのセットを動的に挿入しようとしています。私がしたいと思うのは、列の見出し(表1にある列 - ストレージ表)の「チェックリスト」に読み込まれ、エクスポート表(表2)に存在する場合はすべて表2はその列で可変であるが、一旦インポートされると、潜在的に異なる列構造でインポートされる新しいデータをインポートする。だから私はそれを列名に基づいてインポートする必要があります。PostgreSQL - カラム名の動的INSERT

表1 - ストレージテーブル

ID  NAME  YEAR  LITH_AGE PROV_AGE SIO2 TIO2 CAO MGO COMMENTS 
1  John  1998  2000  3000  65  10  5  5  comment1 
2  Mark  2005  2444  3444  63  8  2  3  comment2 
3  Luke  2001  1000  1500  77  10  2  2  comment3 

表2 - エクスポートテーブル

ID  NAME  MG# METHOD SIO2 TIO2 CAO MGO 
1  Amy  4  Method1 65  10  5  5  
2  Poe  3  Method2 63  8  2  3 
3  Ben  2  Method3 77  10  2  2  

あなたは、ストレージテーブルに存在しない列が含まれるエクスポートテーブルを見ることができるようにこれらは無視されます。

これらの列をすべて一度に挿入したいのですが、列ごとに行を追加すると、挿入のたびに行の数が増えます(おそらく誰かがこの問題を解決できますか?テーブル2にカラム名が存在するかどうかをチェックする関数を記述しました。挿入すると、テーブルの行が毎回拡張され、残りのカラムはNULLとなります)。 私の関数からINSERTライン:「列」は、輸出に存在する列を表すいくつかの変数になり

EXECUTE FORMAT('INSERT INTO table1 (%s) (SELECT (%s) FROM table2)',columns) 

:私の質問のための「コード例」の種類として

EXECUTE format('INSERT INTO %s (%s) (SELECT %s::%s FROM %s);',_tbl_import, _col,_col,_type,_tbl_export); 

にテーブルをストレージテーブルに移動する必要があります。毎回表2が異なるため、これは可変です。

これは、理想的には、表1を更新します:

ID  NAME  YEAR  LITH_AGE PROV_AGE SIO2 TIO2 CAO MGO COMMENTS 
1  John  1998  2000  3000  65  10  5  5  comment1 
2  Mark  2005  2444  3444  63  8  2  3  comment2 
3  Luke  2001  1000  1500  77  10  2  2  comment3 
4  Amy  NULL  NULL  NULL  65  10  5  5  NULL 
5  Poe  NULL  NULL  NULL  63  8  2  3  NULL 
6  Ben  NULL  NULL  NULL  77  10  2  2  NULL 

答えて

0

UPDATED答え

要件を満たしていませんでした私のオリジナルの答えは、後に出てきたが、そのINFORMATION_SCHEMAソリューションの代替例を掲示するように頼まれたとおりここにあります。

Iは、溶液のための2つのバージョンが作られた:

V1 - 既にINFORMATION_SCHEMAを用いた例を所与と等価であるを。しかし、その解決策は、テーブル1カラムDEFAULTに依存しています。意味がある場合、テーブル1に存在しないカラムテーブル2には、DEFAULT NULLがありません。デフォルト値は何でも入力します。

V2 -は、2つのテーブルの列の不一致の場合には 'NULL' を強制的に変更され、TABLE1自身のデフォルト

バージョン1を継承しません:

CREATE OR REPLACE FUNCTION insert_into_table1_v1() 
RETURNS void AS $main$ 

DECLARE 
    columns text; 

BEGIN 

    SELECT string_agg(c1.attname, ',') 
    INTO columns 
    FROM pg_attribute c1 
    JOIN pg_attribute c2 
    ON  c1.attrelid = 'public.table1'::regclass 
    AND  c2.attrelid = 'public.table2'::regclass 
    AND  c1.attnum > 0 
    AND  c2.attnum > 0 
    AND  NOT c1.attisdropped 
    AND  NOT c2.attisdropped 
    AND  c1.attname = c2.attname 
    AND  c1.attname <> 'id'; 

    --  Following is the actual result of query above, based on given data examples: 
    --  -[ RECORD 1 ]---------------------- 
    --  string_agg | name,si02,ti02,cao,mgo 

    EXECUTE format(
     ' INSERT INTO table1 (%1$s) 
      SELECT %1$s 
      FROM table2 
     ', 
     columns 
    ); 

END; 
$main$ LANGUAGE plpgsql; 

バージョン2を:

CREATE OR REPLACE FUNCTION insert_into_table1_v2() 
RETURNS void AS $main$ 

DECLARE 
    t1_cols text; 
    t2_cols text; 

BEGIN 

    SELECT string_agg(c1.attname, ','), 
      string_agg(COALESCE(c2.attname, 'NULL'), ',') 
    INTO t1_cols, 
      t2_cols 
    FROM pg_attribute c1 
    LEFT JOIN pg_attribute c2 
    ON  c2.attrelid = 'public.table2'::regclass 
    AND  c2.attnum > 0 
    AND  NOT c2.attisdropped 
    AND  c1.attname = c2.attname 
    WHERE c1.attrelid = 'public.table1'::regclass 
    AND  c1.attnum > 0 
    AND  NOT c1.attisdropped 
    AND  c1.attname <> 'id'; 

    --  Following is the actual result of query above, based on given data examples: 
    --        t1_cols       |     t2_cols 
    --  --------------------------------------------------------+-------------------------------------------- 
    --  name,year,lith_age,prov_age,si02,ti02,cao,mgo,comments | name,NULL,NULL,NULL,si02,ti02,cao,mgo,NULL 
    --  (1 row) 

    EXECUTE format(
     ' INSERT INTO table1 (%s) 
      SELECT %s 
      FROM table2 
     ', 
     t1_cols, 
     t2_cols 
    ); 

END; 
$main$ LANGUAGE plpgsql; 
何かが不明である場合

はまた、ドキュメントの約のpg_attribute表の列をリンク:https://www.postgresql.org/docs/current/static/catalog-pg-attribute.html

うまくいけば、このことができます:)

+0

私は列でそれを行う必要がある理由として(今追加)の上に指定されている必要があります申し訳ありませんが名。 '表2'は削除され、頻繁に変更されます。テーブル1にデータをインポートするための基本的なテンポラリテーブルです。表2は常に同じ列の組み合わせを持つわけではないため、持っています。私は、テーブル1からどのカラム名が '探しているのか'しか知りません。もし存在すれば、インポートします。 – MattGeo

+0

Ack、それは別の話です。私はあなたがanwserを既に持っているのを見ます:) –

関連する問題