sql >> データベース >  >> RDS >> PostgreSQL

PostgreSQLで関数のない動的列を選択する

    あなたがやろうとしていることは、完全にはほとんど不可能です。

    動的SQLの作成

    まず、できることは次のとおりです do:そのようなクエリのSQLを作成するplpgsql関数:

    CREATE OR REPLACE FUNCTION f_union_common_col_sql(text, text)
     RETURNS text
    AS $function$
    DECLARE 
      _cols text;
    BEGIN
    
    _cols := string_agg(attname, ', ')
    FROM (
        SELECT a.attname
        FROM   pg_attribute a
        WHERE  a.attrelid = $1::regclass::oid
        AND    a.attnum >= 1
        INTERSECT
        SELECT a.attname
        FROM   pg_attribute a
        WHERE  a.attrelid = $2::regclass::oid
        AND    a.attnum >= 1
        ) x;
    
    RETURN 'SELECT ' || _cols || '
    FROM   ' || quote_ident($1) || '
    UNION
    SELECT ' || _cols || '
    FROM   ' || quote_ident($1);
    
    END;
    $function$  LANGUAGE plpgsql;
    
    COMMENT ON FUNCTION f_union_common_col_sql(text, text) IS 'Create SQL to query all visible columns that two tables have in common.
    # Without duplicates. Use UNION ALL if you want to include duplicates.
    # Depends on visibility dicatated by search_path
    $1 .. table1: optionally schema-qualified, case sensitive!
    $2 .. table2: optionally schema-qualified, case sensitive!';
    

    電話:

    SELECT f_union_common_col_sql('myschema1.tbl1', 'myschema2.tbl2');
    

    完全なクエリを提供します。 2回目の呼び出しで実行します。

    ここで使用したほとんどすべてのものは、plpgsql関数のマニュアル> 。
    集計関数string_agg()
    PostgreSQL9.0で導入されました。古いバージョンでは、次のようになります。array_to_string(array_agg(attname), ', ')

    動的SQLを実行しますか?

    次に、ほとんどできないものを次に示します。 行う:

    CREATE OR REPLACE FUNCTION f_union_common_col(text, text)
      RETURNS SETOF record AS
    $BODY$
    DECLARE 
      _cols text;
    BEGIN
    
    _cols := string_agg(attname, ', ')
    FROM (
        SELECT a.attname
        FROM   pg_attribute a
        WHERE  a.attrelid = $1::regclass::oid
        AND    a.attnum >= 1
        INTERSECT
        SELECT a.attname
        FROM   pg_attribute a
        WHERE  a.attrelid = $2::regclass::oid
        AND    a.attnum >= 1
        ) x;
    
    RETURN QUERY EXECUTE '
    SELECT ' || _cols || '
    FROM quote_ident($1)
    UNION
    SELECT ' || _cols || '
    FROM quote_ident($2)';
    
    END;
    $BODY$
      LANGUAGE plpgsql VOLATILE;
    
    COMMENT ON FUNCTION f_union_common_col(text, text) IS 'Query all visible columns that two tables have in common.
    # Without duplicates. Use UNION ALL if you want to include duplicates.
    # Depends on visibility dicatated by search_path
    # !BUT! you need to specify a column definition list for every call. So, hardly useful.
    $1 .. table1 (optionally schema-qualified)
    $2 .. table1 (optionally schema-qualified)';
    

    関数呼び出しでは、ターゲット列のリストを指定する必要があります。したがって、これはほとんど役に立ちません:

    SELECT * from f_union_common_col('myschema1.tbl1', 'myschema2.tbl2')
    
    ERROR:  a column definition list is required for functions returning "record"
    

    これを回避する簡単な方法はありません。関数または少なくとも複合型を動的に作成する必要があります。ここで私は立ち止まります。




    1. PDO::FETCH_ASSOCがすべてをフェッチしていない

    2. RailsプロジェクトでPostgresqlを設定する方法は?

    3. MySQL:LIKEの逆バージョンとは何ですか?

    4. Oracleのデコードに相当するアクセス/ジェット