2016-11-24 25 views
0

関連するテーブルの関連する行を削除するトリガーを作成する必要があります。はい、私はON DELETE CASCADEについて知っていますが、事は私がトリガを使用してそれを行う必要があります。私はそれを数時間Googleに書きましたが、Postgesqlの解決策は見つけられません。私はpostgresql 9.4、pgAdmin IIIを使用します。削除前に関連するレコードを削除するpostgresql

私は以下の表を持っている:

CREATE TABLE "Customer" 
(
    "Id" serial NOT NULL, 
    "ContactPerson" text NOT NULL, 
    "Address" text NOT NULL, 
    "PhoneNumber" "PhoneNumber" NOT NULL, 
    CONSTRAINT "CustomerId (PK)" PRIMARY KEY ("Id") 
) 
WITH (
    OIDS=FALSE 
); 

CREATE TABLE "Order" 
(
    "Id" serial NOT NULL, 
    "OrderDate" date NOT NULL DEFAULT ('now'::text)::date, 
    "Amount" integer NOT NULL DEFAULT 1, 
    "CustomerId" integer NOT NULL, 
    "GoodId" integer NOT NULL, 
    CONSTRAINT "OrderId (PK)" PRIMARY KEY ("Id"), 
    CONSTRAINT "CustomerId (FK)" FOREIGN KEY ("CustomerId") 
     REFERENCES "Customer" ("Id") MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION, 
    CONSTRAINT "GoodId (FK)" FOREIGN KEY ("GoodId") 
     REFERENCES "Good" ("Id") MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION, 
    CONSTRAINT "AmountCheck" CHECK ("Amount" > 0), 
    CONSTRAINT "OrderDateCheck" CHECK ("OrderDate" <= 'now'::text::date) 
) 
WITH (
    OIDS=FALSE 
); 

私はこのクエリを使用してトリガーを作成します。

CREATE FUNCTION DeleteCustomerWithOrders() RETURNS trigger AS $DeleteCustomerWithOrders$ 
    BEGIN 
     DELETE FROM "Order" 
     WHERE "Order"."CustomerId" = (SELECT "Id" FROM "Customer"); 
     RETURN "Customer";   
    END; 
$DeleteCustomerWithOrders$ LANGUAGE plpgsql; 

CREATE TRIGGER DeleteCustomerWithOrders BEFORE DELETE ON "Customer" 
    EXECUTE PROCEDURE DeleteCustomerWithOrders(); 

クエリがうまく動作しますが、その後、私はCustomerから行を削除しようと、それがエラーを取得:

column "Customer" does not exists

(コラム"Customer"は存在しません)

ON INSERTトリガまたはUPDATEトリガの例はドキュメントにありますが、そこにはRETURN NEWが使用されています。また、私はOLDをSQL Serverで使用していました。私の場合は、それの何も役立たない。 WHEREにもエラーがある可能性があります。パトリックへ

UPDATE

感謝。これは第1の問題を解決するが、別の問題を引き起こす。

another problem

エラー:レコードのoldに値が割り当てられていません。詳細:割り当てられていないレコードに対しては、コルテージ構造は定義されていません。

+0

無関係ですが、あなたは本当にそれらの恐ろしい引用符付き識別子を避けるべきです。彼らは長期的にはるかに多くのトラブルですし、それは価値があります。エラーメッセージを英語で投稿すると良いでしょう( 'lc_messages = English'を設定してください) –

+0

' lc_messages = English'スクリプトやpgAdminの設定で書くべきですか?申し訳ありませんが、理解していない、 "恐ろしい引用符付きの識別子"、私の関数名を意味しますか? – QuarK

答えて

1

コードに2つの小さな問題があります。

トリガーはテーブル"Customer"で実行されますが、トリガー機能では、定義済みのパラメーターOLDで削除されているこのテーブルの行を参照します。また、その行からidを選択しないで、それを参照するだけです(サブクエリは実際にテーブルからidをすべて取得しますが、間違っています)。

トリガ機能は次のようになります。あなたが受け取った

CREATE FUNCTION DeleteCustomerWithOrders() RETURNS trigger AS 
$DeleteCustomerWithOrders$ 
BEGIN 
    DELETE FROM "Order" 
    WHERE "Order"."CustomerId" = OLD."Id"; 
    RETURN OLD;   
END; 
$DeleteCustomerWithOrders$ LANGUAGE plpgsql; 

エラーが声明RETURN "Customer";から来ています。 RETURNステートメントは、triggerパラメーターを想定していますが、IDを見つけます。システムはこれをtriggerオブジェクトを返すSELECTステートメントとして解釈しますが、ステートメントは明らかに不完全です。"Customer"は選択リストにあり、列名として解釈されますが、ステートメントを完了するための行ソースはありません。カラム名を解決することはできません。

+0

残念ながら、これはスクリーンショットの問題を解決し、別の原因を解決します。最初のマッサージで更新を見てください。 – QuarK

+0

私が知る限り、トリガー機能には何も問題はありません。おそらくこの関数を直接呼び出していますか(DELETEでは自動的にではなく手動で)? – Patrick

+0

いいえ、私はテーブルのデータビューか 'DELETE FROM'のいずれかを使ってそれを削除していました。どちらの場合も、このエラーが発生します。 – QuarK

関連する問題