3

概念実証として簡単な PG SP を作成しました。ただし、SP を実行するとエラー メッセージが表示されます。スキーマと SP の SQL は次のとおりです。

CREATE TABLE foobar
(
    forename    VARCHAR(255),
    surname     VARCHAR(32),
    enrolement_ts   TIMESTAMP,
    age     SMALLINT,
    major       VARCHAR(32),
    user_id     INTEGER
);


CREATE OR REPLACE FUNCTION insert_foobar (
       forename         VARCHAR(255),
       surname          VARCHAR(32),
       age      SMALLINT,
       major        VARCHAR(32) ) RETURNS VOID AS $$
    INSERT INTO foobar VALUES (forename, surname, getdate(), age, major, user_id());
$$ LANGUAGE sql;

コマンド ラインで関数定義を入力すると、次のエラーが発生します。

ERROR:  column "forename" does not exist
LINE 6:     INSERT INTO foobar VALUES (forename, surname,...
                                           ^

このエラーの原因を特定/説明できる人はいますか? 明らかに、列 forename はテーブル スキーマに存在するため、エラー メッセージがわかりません。

4

1 に答える 1

6

PostgreSQL 9.2 より前では、純粋な SQL (pl/pgSQL などの手続き型言語ではなく) で記述された関数への引数は、関数シグネチャにそれらを含めることができたとしても (「ドキュメント目的で」)、名前付きパラメーターを名前で参照できませんでした。

SQL 関数に関する現在のマニュアル ページには、次の注記が含まれています。

注: 名前を使用して SQL 関数の引数を参照する機能は、PostgreSQL 9.2 で追加されました。古いサーバーで使用される関数は、$n 表記を使用する必要があります。

そのため、9.2 より前のバージョンを使用するには、関数を次のようにする必要があります。

CREATE OR REPLACE FUNCTION insert_foobar (
       forename         VARCHAR(255),
       surname          VARCHAR(32),
       age      SMALLINT,
       major        VARCHAR(32) ) RETURNS VOID AS $$
    INSERT INTO foobar VALUES ($1, $2, getdate(), $3, $4, user_id());
$$ LANGUAGE sql;

(私は、ローカルで定義された関数がラップされており、ユーザー ID に必要なロジックが何であれ、それを想定getdate()しています。)user_id()now()

于 2013-11-07T00:30:33.440 に答える