2

テーブル (Id、FK、Date1、Date2) があり、ブール値を返す関数を作成する必要があります。通常、指定された FK に一致するレコードを選択し、いくつかの追加ステートメントをチェックしたいと考えています。select ステートメントが 0 行を返す場合は true を返し、それ以外の場合は false を返します。私はすでにこのコードを書いています:

CREATE FUNCTION isAlreadyTaken(FK INT4, Date1 DATE, Date2 DATE)
  RETURNS BOOLEAN
AS $$
BEGIN
  CREATE TEMP TABLE helper ON COMMIT DROP AS SELECT COUNT(table.FK) AS quant 
    FROM table
    WHERE table.FK = FK AND table.Date2 IS NULL;
  SELECT CASE
    WHEN helper.quant > 0
    THEN FALSE
    ELSE TRUE 
  END;
END
$$ LANGUAGE plpgsql;

コードはコンパイル中であり、実行できます。しかし、CHECK ステートメントで関数を呼び出すと、エラー [42P01] が返されます。解決策は実際に機能するものに近いですか、それとも完全に道に迷ってしまいましたか?

4

1 に答える 1

6

COUNT(...) > 0 WHERE ...は と同等EXISTS(select ... where ...)で、 EXISTS(table expression) すでにブール値を生成しています:

EXISTS (
 SELECT *
 FROM table t
 WHERE t.FK = FK AND t.Date2 IS NULL
 )

それをクエリに入れます(Date1およびDate2引数は使用されていないように見えることに注意してください...)

CREATE FUNCTION isAlreadyTaken1(FK INT4, Date1 DATE, Date2 DATE)
  RETURNS BOOLEAN
AS $$
BEGIN
  RETURN EXISTS (
    SELECT 1
    FROM table t
    WHERE t.FK = FK 
         AND t.Date2 IS NULL    -- <<-- this looks nonsensical
        );
END
$$ LANGUAGE plpgsql;

そして、@a_horse_with_no_name がコメントしたように: plpgsql さえ必要ありません。単純な SQL だけで十分です:

CREATE FUNCTION isAlreadyTaken1a(FK INT4, Date1 DATE, Date2 DATE)
  RETURNS BOOLEAN
AS $func$
  SELECT EXISTS (
    SELECT 1
    FROM table t
    WHERE t.FK = FK
         AND t.Date2 IS NULL    -- <<-- this looks nonsensical
        );
$func$ LANGUAGE sql;

ところで:ロジックを逆にしました。IMO allreadyTakenは を意味しcount() > 0ます。

于 2016-12-07T20:17:33.823 に答える