17

PostgreSQL 9.2 を使用しており、列に条件付き制約を追加する必要があります。基本的に、他の 2 つの列に特定の値がある場合、その列が false であることを確認したいと考えています。

gid          | int_unsigned           | not null default 0
realm        | character varying(255) | not null default ''::character varying
grant_update | smallint_unsigned      | not null default (0)::smallint
grant_delete | smallint_unsigned      | not null default (0)::smallint

例:

alter table node_access add constraint block_anonymous_page_edit
check (grant_update = 0 WHERE (gid = 1 AND realm = 'nodeaccess_rid'));

これがすべきことは、gid が 1 で realm = nodeaccess_rid の場合、grant_update が 0 であることを確認することです。ただし、私がやりたいことをするのではなく、実際にはすべての列がこれらの値を模倣しようとしていると思います。つまり、grant_update が常に 0、gid が常に 1、レルムが常に nodeaccess_rid であることを確認しようとしています。私が得るエラーは次のとおりです。

ERROR:  check constraint "block_anonymous_page_edit" is violated by some row

編集

これは、更新時にトリガーされる機能でなければならないと思います。

編集

上記の質問に行を追加したため、承認済みのソリューションを以下のコメントで更新しました。

4

3 に答える 3

31

ロジックを理解したら、それは単純なCHECK制約です。

CREATE TABLE tbl (
  gid          int      NOT NULL DEFAULT 0
, realm        text     NOT NULL DEFAULT ''
, grant_update smallint NOT NULL DEFAULT 0
, CONSTRAINT block_anonymous_page_edit
  CHECK (gid <> 1 OR realm <> 'nodeaccess_rid' OR grant_update = 0)
);

テスト:

-- these work:
INSERT INTO tbl(gid, realm, grant_update)
VALUES (1, 'nodeaccess_rid', 0);

INSERT INTO tbl(gid, realm, grant_update)
VALUES (1, 'some_string',    1);

INSERT INTO tbl(gid, realm, grant_update)
VALUES (2, 'nodeaccess_rid', 1);

-- check violation!
INSERT INTO tbl(gid, realm, grant_update)
VALUES (1, 'nodeaccess_rid', 1);

デシベル<>ここでフィドル

于 2013-02-10T07:37:33.480 に答える
2

これをきっかけに書きます。これにより、エラーを発生させる (場合によっては最適にテストできるカスタム コードを使用する) か、単に問題を処理して、gid=1 および realm = 'nodeaccess_rid' の場合に grant_update = 0 を設定するかのいずれかの柔軟性が得られます。

于 2013-02-08T16:03:55.930 に答える
-2

結局、トリガー機能を使用しました。これにより、ロールがチェックされ、不要な機能がブール値のようなフィールド grant_update および grant_delete でオフに設定されます。以下の関数も、grant_view 値を上書きするのではなく保持します。

CREATE OR REPLACE function block_anonymous_page_edit()
RETURNS trigger AS $function$
BEGIN
  IF NEW.gid = 1 AND NEW.realm != 'nodeaccess_author' AND (NEW.grant_update = 1 OR NEW.grant_delete = 1) THEN
    RAISE WARNING 'Anonymous users are not allowed to edit pages.';
    NEW.grant_update := 0;
    NEW.grant_delete := 0;
  END IF;
  RETURN NEW;
END;
$function$ LANGUAGE plpgsql;

CREATE TRIGGER tgr_block_anonymous_page_edit BEFORE INSERT OR UPDATE ON node_access FOR EACH ROW EXECUTE PROCEDURE block_anonymous_page_edit();
于 2013-02-08T21:10:54.980 に答える