2016-12-09 7 views
1

私はテーブルmoredataに参加したい共通の状況があります。最も単純な例を与えるために、私が持っている想像:moredataは同じままながらテーブルを入力としてPostgreSQL関数? plpgsql関数の動的SQLは行く方法ですか?

SELECT * 
FROM x 
JOIN moredata d on x.yyyymmdd = d.yyyymmdd 

xが異なります。 コードを再利用するための良い方法はありますか?上記を自動化して、異なるテーブルに適用できるようにしてください(例えば、 'x'の代わりに 'y'テーブルで同じことをします)?

表の名前で動作する動的SQLを使用してplpgsql関数を作成する方法もあります。ような何か:

CREATE FUNCTION joinmoredata(tblname text) RETURNS TABLE(...) AS $$ 
BEGIN 
    RETURN QUERY EXECUTE format('SELECT * FROM %I JOIN moredata on ...', tblname); 
END; 
$$ LANGUAGE plpgsql; 

しかし、その後、あなたは、派生テーブルまたはCTEにそれを適用できませんでした。より良い方法がありますか?または、動的SQLは、この状況でコードを再利用する最良の方法ですか?

(注、実際のクエリは、私は、コードを再利用したい理由であるSELECT * FROM x JOIN moredata d on x.yyyymmdd = d.yyyymmddよりも多く複雑です。)

+0

関数の戻り値は何ですか? –

+0

'xは変化するでしょう '..どのくらい正確に?各テーブルに同じ列がありますか? (タイプ、名前、番号)?戻り値の型 'RETURNS TABLE(...)'も変わるでしょうか? –

+0

@ErwinBrandstetter 'x'は、毎回同じカラムを持ち、関数が返すテーブルが毎回同じカラムを持つように標準化することができます。 –

答えて

2

xの代わりに各テーブルの同じデータ型を使用して同じ列名を使用し、同じ行タイプを返す限り、これは動的SQLの候補になります。あなたの質問に既にあなたがいるのとまったく同じです。 format()%Iを使用すると、識別子のサニタイズ方法がわかっているため、構文エラーやSQLインジェクションを避けることができます。

特権管理の計画が必要です。また、スキーマ修飾テーブル名またはデータ型regclassを渡して、テーブル名の解決や他のテーブルと同じ名前の別のスキーマとの混同を避けることができます。

密接に関連して詳細:

それはより複雑になった場合 - カラム名と型変化 - あなたはいつも...

クライアントプログラムでは、クエリ文字列を連結することができます
1

私は、動的SQL私はSQLの大きな部分を再利用するために必要なすべての時間を使用することだけを言うことができますコードを変更し、WHERE句やテーブル名などのものだけを変更してください。これは正常に動作し、INSERTやUPDATESを含む非常に複雑なCTEクエリも同様に動作します。だから私は動的SQLを投票します。

関連する問題