0

INSERT INTOソースのテーブル名と列名をパラメーターとして使用してクエリを作成する方法を理解しようとしています。

手始めに、ソーステーブル名をパラメータ化しようとしていました。次のクエリを書きました。今のところ、変数の値をtablename直接宣言して割り当てていますが、実際の例では、他のソース/リストから取得されます。ターゲット テーブルには 1 つの列しかありません。

CREATE OR REPLACE FUNCTION foo()
RETURNS void AS
$$
DECLARE
    tablename text;
BEGIN
   tablename := 'Table_1';
   EXECUTE 'INSERT INTO "Schemaname"."targettable"
   SELECT "Col_A"
   FROM "schemaname".'
   ||quote_ident(tablename);
END
$$ LANGUAGE PLPGSQL;

クエリはエラーなしで実行されますが、変更はターゲット テーブルに反映されません。クエリを実行すると、次の出力が得られます。

クエリ OK、影響を受ける行は 0 (実行時間: 296 ミリ秒、合計時間: 296 ミリ秒)

変更をターゲット テーブルに反映させたい。問題を解決する方法がわかりません。

4

1 に答える 1

1

監査済みコード

CREATE OR REPLACE FUNCTION foo()
   RETURNS void AS
$func$
DECLARE
   _tbl text := 'Table_1';  -- or 'table_1'?
BEGIN       
   EXECUTE 'INSERT INTO schemaname.targettable(column_name)
   SELECT  "Col_A"
   FROM    schemaname.' || quote_ident(_tbl);  -- or "Schemaname"?
END
$func$  LANGUAGE plpgsql;
  • INSERT永続化されたステートメントには、常に明示的なターゲット リストを使用します。

  • 宣言時に変数を割り当てることができます。

  • 不正なスペリングを維持するために二重引用符で囲まれた識別子を使用することは、広く普及している愚かさです。存在する残りの名前を二重引用符で囲み続ける必要があります。これらのエラーの 1 つ以上がコードに忍び込んでいるようです:"Schemaname"または"schemaname"? Table_1または"Table_1"

  • テーブル名などの識別子をtextパラメーターとして指定し、それを でエスケープするとquote_ident()、大文字と小文字が区別されます。
    二重引用符で囲まれていない限り、SQL コードの識別子は小文字にキャストされます。ただし、quote-ident()( SQL インジェクションを防ぐために使用する必要があります) は、必要に応じて二重引用符で指定したスペルを保持します。

パラメータ付き関数

CREATE OR REPLACE FUNCTION foo(_tbl text)
   RETURNS void AS
$func$
BEGIN       
   EXECUTE 'INSERT INTO schemaname.targettable(column_name)
   SELECT  "Col_A"
   FROM    schemaname.' || quote_ident(_tbl);
END
$func$  LANGUAGE plpgsql;

電話:

SELECT foo('tablename');  -- tablename is case sensitive

他の方法があります:

于 2015-04-13T23:03:43.420 に答える