sql >> データベース >  >> RDS >> PostgreSQL

削除後にリモートデータベースに行を挿入するトリガー

    これは、レプリケーションの限定されたアプリケーションです。要件は大きく異なるため、さまざまな状況に対応するさまざまな確立されたソリューションがあります。 マニュアルの概要を検討してください。

    手編みのトリガーベースのソリューションは、比較的少数の実行可能なオプションの1つです。 削除。行ごとに個別の接続を開いたり閉じたりすると、かなりのオーバーヘッドが発生します。他にもさまざまなオプションがあります。

    ながら dblinkでの作業私はいくつかの変更を提案します。最も重要なこと:

    • format()を使用する 文字列をよりエレガントにエスケープします。

    • 行全体を渡す すべての列を通過およびエスケープする代わりに。

    • すべてのトリガー機能にパスワードを設定しないでください。
      FOREIGN SERVERを使用してください プラスUSER MAPPING 。詳細な手順はこちら:

    基本的に、1回実行します ソースサーバー上:

    CREATE SERVER myserver FOREIGN DATA WRAPPER dblink_fdw
    OPTIONS (hostaddr '127.0.0.1', dbname 'gtr_bd_archive');
    
    CREATE USER MAPPING FOR role_source SERVER myserver
    OPTIONS (user 'postgres', password 'secret');
    

    できれば、ターゲットサーバーにスーパーユーザーとしてログインしないでください。特権の昇格を回避するために、特権が制限された専用の役割を使用してください。

    そして、パスワードファイル を使用します パスワードなしのアクセスを許可するためにターゲットサーバー上で。このようにして、パスワードをUSER MAPPINGに保存する必要さえありません。 。この関連する回答の最後の章の説明:

    次に:

    CREATE OR REPLACE FUNCTION pg_temp.flux_tresorerie_historique_backup_row()
      RETURNS trigger AS
    $func$
    BEGIN
       PERFORM dblink_connect('myserver');  -- name of foreign server from above
    
       PERFORM dblink_exec( format(
       $$
       INSERT INTO flux_tresorerie_historique  -- provide target column list!
       SELECT (r).id_flux_historique
            , (r).date_operation_flux
            , (r).date_valeur_flux
            , (r).date_rapprochement_flux::date  -- 'YYYY-MM-DD' is default ISO format anyway
            , (r).libelle_flux
            , (r).montant_flux
            , (r).contre_valeur_dzd
            , (r).rib_compte_bancaire
            , (r).frais_flux
            , (r).sens_flux
            , (r).statut_flux
            , (r).code_devise
            , (r).code_mode_paiement
            , (r).code_agence
            , (r).code_compte
            , (r).code_banque
            , (r).date_maj_flux
            , (r).statut_frais
            , (r).reference_flux
            , (r).code_commission
            , (r).id_flux
       FROM   (SELECT %L::flux_tresorerie_historique) t(r)
       $$, OLD::text));  -- cast whole row type
    
       PERFORM dblink_disconnect();
       RETURN NULL;  -- only for AFTER trigger
    END
    $func$  LANGUAGE plpgsql;
    

    行タイプが一致しない場合は、ターゲットテーブルの列のリストを詳しく説明する必要があります。

    これについて真剣に考えている場合:

    つまり、行全体を挿入します ターゲットの行タイプが同じである(タイムスタンプから日付を抽出しないなど)ので、行全体をさらに簡単に渡すことができます。

    CREATE OR REPLACE FUNCTION flux_tresorerie_historique_backup_row()
      RETURNS trigger AS
    $func$
    BEGIN
       PERFORM dblink_connect('myserver');  -- name of foreign server
    
       PERFORM dblink_exec( format(
       $$
       INSERT INTO flux_tresorerie_historique
       SELECT (%L::flux_tresorerie_historique).*
       $$
       , OLD::text));
    
       PERFORM dblink_disconnect();
       RETURN NULL;  -- only for AFTER trigger
    END
    $func$  LANGUAGE plpgsql;
    

    関連:



    1. Connector.php行47のPDOException:SQLSTATE[HY000][1045]ユーザー'hassan'@'localhost'のアクセスが拒否されました(パスワードを使用:YES)

    2. MySQLデータベースからデータを削除する

    3. SQL Server:アセンブリ'Test'の形式が正しくないか、純粋な.NETアセンブリではないため、アセンブリ'Test'のCREATEASSEMBLYが失敗しました。

    4. Oracleで2列のデータをA、B形式で取得する方法