2

PostgreSQLがとにかくその外部キー制約をチェックする場合、別のテーブルのレコードが実際に存在することを本当にチェックする必要がありますか?

parent通常、レコードを作成する前に、既存のレコードがあるかどうかを確認しますchild。しかし、実行するのは別のクエリです。parentしたがって、PostgreSQLエラーを処理して、レコードが存在しない(外部キー制約に違反している)かどうかを確認する方がよいと思います。

データベースサーバーの機能を利用する方が良いのでしょうか、それともこの目的のためのメンターではなかったのでしょうか。新しいレコードを作成する前に、すべての整合性チェックを実行することをお勧めしますか?

CREATE TABLE "public"."categories" (
    "id" serial,
    "name" varchar(100),
    CONSTRAINT "categories__id_pkey" PRIMARY KEY ("id")
);

CREATE TABLE "public"."products" (
    "id" serial,
    "category_id" integer NOT NULL,
    "name" varchar(100),
    CONSTRAINT "products__id_pkey" PRIMARY KEY ("id"),
    CONSTRAINT "products__category_id_fkey" FOREIGN KEY ("category_id")
        REFERENCES "categories" ("id") ON DELETE CASCADE
);

擬似コード:

if (query("SELECT * FROM categories WHERE id = 123"))
    query("INSERT INTO products (category_id, name) VALUES (123, 'Something')")
else
    throw Error("Parent record does not exist")

try
    query("INSERT INTO products (category_id, name) VALUES (123, 'Something')")
catch (Exception e)
    if (e.code == '23503')
        throw Error("Parent record does not exist")
    else
        throw Error("Some other error occured")

23503PostgreSQLのエラーコードは次のとおりです。

ERROR: insert or update on table "products" violates foreign key constraint "products__category_id_fkey"

4

1 に答える 1

5

データベースサーバーの機能を利用する方が良いのでしょうか、それともこの目的のためのメンターではなかったのでしょうか。

それはまさにその目的のためのものでした。

エラーを処理するだけです。そうしないと、作業が多すぎます。

関連する行の存在を確認する場合は、PostgreSQLでも実行されるため、作業を複製するだけです。

行を挿入する順序を気にしたくない場合は、制約をとして宣言できますdeferrable initially deferred。その場合、各ステートメントを実行するときではなく、トランザクションをコミットするときに、関連するすべての行が存在する必要があります。簡単な例を次に示します。http://sqlfiddle.com/#!12 / 33de1 / 1

その場合、各ステートメントを実行するときではなく、コミットするときにエラーを処理する必要があります。

于 2012-10-23T16:30:50.413 に答える