5

私が使用するテーブルを作成するには:

CREATE TABLE category
(
  cat_id serial NOT NULL,
  cat_name character varying NOT NULL,
  parent_id integer NOT NULL,
  CONSTRAINT cat_id PRIMARY KEY (cat_id)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE category
  OWNER TO pgsql;

parent_id は、別のカテゴリの ID です。今、私は問題を抱えています:削除レコードをその子とカスケードするにはどうすればよいですか? parent_id を cat_id への外部キーとして設定する必要があります。私はこれを試します:

  ALTER TABLE category 
ADD CONSTRAINT cat_cat_id_fkey FOREIGN KEY (parent_id)
      REFERENCES category (cat_id) MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE CASCADE

しかし、それは次のようになります:

ERROR:  insert or update on table "category" violates foreign key constraint "cat_cat_id_fkey"
DETAIL:  Key (parent_id)=(0) is not present in table "category".
4

3 に答える 3

6

あなたが抱えている問題 -parent_id階層の最上位にあるカテゴリは何ですか?

もしそうなら、それは制約nullを破るでしょうNOT NULL

のような任意の数値0になると、外部キーが壊れます(例のように)。

一般的な解決策 - に制約をドロップNOT NULLし、トップ カテゴリparent_idに設定parent_idします。null

于 2013-06-29T10:45:24.210 に答える
3
-- create some fake data for testing
--
DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;
CREATE TABLE category

(
  cat_id serial NOT NULL,
  cat_name character varying NOT NULL,
  parent_id integer NOT NULL,
  CONSTRAINT cat_id PRIMARY KEY (cat_id)
);

INSERT INTO category(cat_name,parent_id)
SELECT 'Name_' || gs::text
        , gs % 3
FROM generate_series(0,9) gs
        ;

        -- find the records with the non-existing parents
SELECT ca.parent_id , COUNT(*)
FROM category ca
WHERE NOT EXISTS (
        SELECT *
        FROM category nx
        WHERE nx.cat_id = ca.parent_id
        )
GROUP BY ca.parent_id
        ;

        -- if all is well: proceed
        -- make parent pointer nullable
ALTER TABLE category
        ALTER COLUMN parent_id DROP NOT NULL
        ;

        -- set non-existing parent pointers to NULL
UPDATE category ca
SET parent_id = NULL
WHERE NOT EXISTS (
        SELECT *
        FROM category nx
        WHERE nx.cat_id = ca.parent_id
        )
        ;

        -- Finally, add the FK constraint
ALTER TABLE category
        ADD CONSTRAINT cat_cat_id_fkey FOREIGN KEY (parent_id)
              REFERENCES category (cat_id) MATCH SIMPLE
              ON UPDATE CASCADE ON DELETE CASCADE
        ;
于 2013-06-29T12:21:56.510 に答える
1

これは非常に簡単です。
ここで、外部キーparent_idは を参照しcat_idます。
ここに のレコードはparent_id=0存在しますが、 のレコードはありませんcat_id=0

于 2013-09-16T06:21:52.293 に答える