2016-11-18 57 views
0

私はPostgreSQLで動的SQLを使用しようとしています。私はフィールドをdb_rowレコードから別のEXECUTEステートメントで使用しようとしています。フィールドidはレコード変数に設定されているが、私はまだエラーを取得:postgresql、レコードデータ型のカラムを特定できませんでした

ERROR: could not identify column "id" in record data type 
LINE 1: SELECT $1.id FROM audit.portfolio WHERE alter_type = 'INSERT... 
      ^
QUERY: SELECT $1.id FROM audit.portfolio WHERE alter_type = 'INSERT' AND id = $1.id 
CONTEXT: PL/pgSQL function inline_code_block line 14 at EXECUTE 

これは私のデータとテスト機能である:

CREATE TABLE IF NOT EXISTS public.portfolio 
(
    id INTEGER NOT NULL, 
    name CHARACTER VARYING, 
    CONSTRAINT portfolio_pkey PRIMARY KEY (id) 
) 
WITH (OIDS = FALSE); 

CREATE TABLE IF NOT EXISTS audit.portfolio 
(
    alter_type TEXT, 
    id   INTEGER NOT NULL, 
    name  CHARACTER VARYING, 
    CONSTRAINT portfolio_pkey PRIMARY KEY (id) 
) 
WITH (OIDS = FALSE 
); 

INSERT INTO public.portfolio (id, name) VALUES (1, 'NAME 1'), (2, 'NAME 2'); 

-- temp function 
DO $$ 
DECLARE 
    db_row RECORD; 
    pk_val BIGINT; 

BEGIN 

    FOR db_row IN EXECUTE format(
     'SELECT *, 100 AS created_by_id, %L::TIMESTAMP AS creation_time FROM public.%I ORDER BY %I', 
     '2014-01-01 00:00:00', 'portfolio', 'id', 'id') 
    LOOP 
    RAISE NOTICE 'db_row.id: %', db_row.id; 
    EXECUTE 
    format(
     'SELECT $1.%I FROM audit.%I WHERE alter_type = %L AND %I = $1.%I', 
     'id', -- this will be dynamic and change when table change 
     'portfolio', -- this will be dynamic and change when table change 
     'INSERT', 
     'id', -- this will be dynamic and change when table change 
     'id' -- this will be dynamic and change when table change 
    ) 
    INTO pk_val 
    USING db_row; 
    RAISE NOTICE 'pk_val: %', pk_val; 
    END LOOP; 
END$$; 

それはpostgresのEXECUTE ... USING db_rowのように思えるが似ているdb_rowの完全な構造を見ていません行はテーブルからです。

私の最終目標は、既存のテーブル名 これを行う取る関数を作成することです:

EXECUTE 
    format(
     'SELECT $1.%I FROM audit.%I WHERE alter_type = %L AND %I = $1.%I', 
     'primary_key_col', 
     'table_name', 
     'INSERT', 
     'primary_key_col', 
     'primary_key_col' 
    ) 
    INTO pk_val 
    USING db_row 

このEXECUTE文でdb_row.id値を使用するpostgresのを伝えるためにどのように?

+0

多分これは助けることができます。 http://stackoverflow.com/questions/14065271/how-to-use-execute-format-using-in-postgres-function – McNets

+0

この例では、テーブル名、カラム、プライマリキー名を知っています。しかし、実際のコードでは私はしません。だから私は 'USING db_row.id、db_row.col2'などは使用できません。 – piotrekkr

答えて

1

タイプrecordのパラメータ(db_row)をSQL文に渡していますが、この値にはSQLエンジンの既知の構造はありません。テーブルタイプにキャストすることさえできません。

醜い回避策レコードを型出力関数を呼び出すことで動作するテキスト表現に変換し、テストを目的のテーブル型にキャストすることができます。

これは私が何を意味するかを示すサンプルコードです:

DO $$ 
DECLARE 
    r record; 
    n name; 
BEGIN 
    /* find all tables with a column "oid" */ 
    FOR r IN 
     SELECT t.* 
     FROM pg_class t 
       JOIN pg_attribute a ON a.attrelid = t.oid 
     WHERE a.attname = 'oid' 
    LOOP 
     /* get the table name */ 
     EXECUTE format(
       'SELECT ($1::text::%s).relname', 
       'pg_class' 
      ) INTO n USING r; 
     RAISE NOTICE 'Table name: %', n; 
    END LOOP; 
END; 
$$; 
関連する問題