1

INSERTslony を使用してレプリケートされたデータベースに取り組んでおり、テーブルに対する操作の後にトリガーされるトリガーを作成しようとしています。

このトリガーでは、dblink を使用して同じデータベースの別のテーブルを更新しようとしています。しかし、2 番目のテーブルを更新しようとすると、最初のテーブルに挿入した値が存在しないというエラーが表示されます。
通常の UPDATE ステートメントで 2 番目のテーブルを更新すると、slony 同期がトリガーされないため、dblink を使用しています。

最初のテーブル:

CREATE TABLE "COFFRETS"
(
  "NUM_SERIE" character varying NOT NULL,
  "DATE_CREATION" timestamp without time zone NOT NULL DEFAULT now(),
  "DATE_DERNIERE_MODIF" timestamp without time zone NOT NULL DEFAULT now(),
  "NOMENCLATURE" integer NOT NULL,
  "COMMANDES_DETAILS_ID" integer,
  "DEBLOCAGES_ID" integer,
  "ETAT" integer NOT NULL DEFAULT 1,
  "EXPEDITIONS_ID" bigint,
  "STOCKISTE_EXPE_ID" integer,
  "STOCKISTE_RCPT_ID" integer,
  "SITE_ID" integer,
  "FACTURES_ID" integer,
  "CMDDETECH_ID" integer,
  "FACTURE_AVE_ID" integer,
  "SHIPPING_ID" integer,
  "SYNCHRONISE" boolean DEFAULT false,
  CONSTRAINT "COFFRETS_pkey" PRIMARY KEY ("NUM_SERIE"),
  CONSTRAINT "FK_SHIPPING" FOREIGN KEY ("SHIPPING_ID")
      REFERENCES "SHIPPING" ("ID") MATCH SIMPLE
);

2 番目のテーブル:

CREATE TABLE "SHIPPING"
(
  "DATE_AJOUT" timestamp without time zone NOT NULL,
  "DATE_DERNIERE_MODIF" timestamp without time zone NOT NULL,
  "ORDRE_PRODUCTION" text,
  "AIRE_APPRO" text,
  "DATE_ENVOI" timestamp without time zone,
  "DATE_LIVRAISON" timestamp without time zone,
  "REF_CARRIER" text,
  "QTE" numeric,
  "NUM_CONTRAT" text,
  "COMMENTAIRES" text,
  "ID" serial NOT NULL,
  "POSTE_TRAVAIL" text,
  "POSTE_CONTRAT" integer,
  CONSTRAINT "Pkey_ID_SHIPPING" PRIMARY KEY ("ID")
);

引き金:

CREATE TRIGGER test
  AFTER INSERT
  ON "SHIPPING"
  FOR EACH ROW
  EXECUTE PROCEDURE "AffectationShipping"();

トリガー機能:

CREATE OR REPLACE FUNCTION "AffectationShipping"()
  RETURNS trigger AS
$BODY$DECLARE   
    coffretNumSerie text;
    message text;
    num_site    integer;
    txt text;

BEGIN   

    RAISE NOTICE '-----------------------------------------------------------------------------'; 
    RAISE NOTICE '-                     AffectationShipping                                   -'; 
    RAISE NOTICE '-----------------------------------------------------------------------------'; 

    --lecture du numéro de site
    num_site=0;
    SELECT "Value" INTO num_site FROM "APPLICATION_PARAMETERS" WHERE "Name" = 'SITE_ID';

    --Récupération du coffret concerné. un seul coffret car on a un shipping par coffret chez aquasnap
    SELECT  "COFFRETS"."NUM_SERIE" INTO coffretNumSerie
    FROM    "COFFRETS" INNER JOIN "DEBLOCAGES" ON 
            "COFFRETS"."DEBLOCAGES_ID" = "DEBLOCAGES"."ID" 
    WHERE   "COFFRETS"."SHIPPING_ID" IS NULL AND 
            "DEBLOCAGES"."NumOrdreProduction" = NEW."ORDRE_PRODUCTION"
    LIMIT 1;

    IF coffretNumSerie != '' THEN
    RAISE NOTICE 'ID = %', NEW."ID";
    RAISE NOTICE 'param = %', (SELECT parametre_get('Chaine_connexion_bdd_Atelier')::text);
    RAISE NOTICE 'Statement = %', ('UPDATE "COFFRETS" SET "SHIPPING_ID" = ' || NEW."ID" || '  WHERE "NUM_SERIE" = ''' ||coffretNumSerie ||''';');
        PERFORM dblink_exec((SELECT parametre_get('Chaine_connexion_bdd_Atelier'))::text, ('UPDATE "COFFRETS" SET "SHIPPING_ID" = ' || NEW."ID" || '  WHERE "NUM_SERIE" = ''' ||coffretNumSerie ||''';'));
        RAISE NOTICE 'Affectation du shipping Num.[%], ordre de production Num.[%] au coffret Num.[%].',  NEW."ID" ,NEW."ORDRE_PRODUCTION",coffretNumSerie;
        --Log d'un message d'information
        message = 'Affectation du shipping Num.['|| NEW."ID" ||'], ordre de production Num.['|| NEW."ORDRE_PRODUCTION" ||'] au coffret Num.['|| coffretNumSerie ||'].';
        --enregistrement de l'information
        INSERT INTO "ERRORS_LOG" ("DATE","MESSAGE","ERROR_TYPES","LOCALIZATION", "TYPE_MESSAGE_ID", "SITE_ID" )
        VALUES (now(),message,'Information' ,'Trigger associations coffrets - Shipping : AffectationShipping',4,num_site);
    ELSE --LogErreur

        RAISE NOTICE 'Aucun coffret correspondant au shipping Num.[%], ordre de production Num.[%].' , NEW."ID" ,NEW."ORDRE_PRODUCTION" ;

        --composition du message d'erreur
        message = 'Aucun coffret correspondant au shipping Num.['|| NEW."ID" ||'], ordre de production Num.[' || NEW."ORDRE_PRODUCTION" || '].';
        --enregistrement de l'erreur de type "Gestion COFFRETS"     

        INSERT INTO "ERRORS_LOG" ("DATE","MESSAGE","ERROR_TYPES","LOCALIZATION", "TYPE_MESSAGE_ID", "SITE_ID" )
        VALUES (now(),message,'Erreur' ,'Trigger associations coffrets - Shipping : AffectationShipping',3,num_site);

    END IF; 

    RAISE NOTICE '-----------------------------------------------------------------------------'; 
    RAISE NOTICE '-Fin                      AffectationShipping                               -'; 
    RAISE NOTICE '-----------------------------------------------------------------------------'; 

    RETURN NEW;
END;$BODY$
  LANGUAGE plpgsql;

エラー メッセージについては、PostgreSQL でメッセージを英語で出力する方法がわかりません。

SHIPPING_ID基本的に、出荷テーブルに外部キーが存在しないと言っています。

奇妙なことは、それを使用せずに更新しようとすると正常に動作するdblink_execことです。しかし、前に言ったように、slony が更新を認識できるように、dblink を介してこの更新を行う必要があります。

4

1 に答える 1

2

dblinkの接続でターゲット データベースにアクセスすることによって動作します。これには、いくつかの固有の結果があります。

  • dblink は、別の (準「自律型」) トランザクションで実行されます。
  • dblink コマンドの効果はロールバックできません。

そして、あなたにとって最も重要なこと:

  • 別のトランザクションで実行されるため、まだコミットされていない呼び出しトランザクションの変更を確認できません。
于 2014-03-14T01:10:12.620 に答える