IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Administration PostgreSQL Discussion :

Logger les modifications dans une BD


Sujet :

Administration PostgreSQL

  1. #1
    Membre régulier
    Inscrit en
    Novembre 2003
    Messages
    245
    Détails du profil
    Informations forums :
    Inscription : Novembre 2003
    Messages : 245
    Points : 106
    Points
    106
    Par défaut Logger les modifications dans une BD
    Bonjour,

    Je cherche une façon de logger les modifications faites dans une base de données, pour pouvoir les répercuter facilement sur une autre base (sans faire de comparaisons).

    J'avais pensé déposer des triggers sur chaque table, et enregistrer pour chaque action, le nom de la table, et la valeur de chacun des identifiants. Hélas, c'est assez complexe de faire quelque chose de générique.

    N'y a-t-il pas un moyen de stocker une référence vers une ligne d'une table ? Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE TABLE differences (
        table TEXT,
        row RECORD
    );
     
    CREATE OR REPLACE FUNCTION diff_triggers_exec() RETURNS TRIGGER AS $diff_triggers_exec$
    DECLARE
    BEGIN
        INSERT INTO differences(table, row) VALUES(TG_TABLE_NAME, NEW);
        RETURN NULL;
    END;
    $diff_triggers_exec$ LANGUAGE plpgsql;
    Une autre solution serait de modifier chaque table à surveiller, en ajoutant un boolean "new", mais ça oblige à modifier le schéma.

    Voyez-vous un autre mécanisme permettant d'enregistrer de façon assez générique les modifications faites sur un ensemble de tables ?

    Merci.

  2. #2
    Membre régulier
    Inscrit en
    Novembre 2003
    Messages
    245
    Détails du profil
    Informations forums :
    Inscription : Novembre 2003
    Messages : 245
    Points : 106
    Points
    106
    Par défaut
    J'ai trouvé un système pour ajouter ou supprimer dynamiquement un tag sur les tables surveillées :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    -- Synchronized tables
    CREATE TABLE sync_tables (
    	st_name TEXT PRIMARY KEY
    );
     
    -- Manage the sync tag on synchronized tables
    CREATE OR REPLACE FUNCTION sync_tag() RETURNS TRIGGER AS $diff_triggers_set$
    DECLARE
    	TAG_NAME CONSTANT TEXT := 'sync_tag';
    	request TEXT;
    	tagged BOOLEAN;
    BEGIN
     
    	IF(TG_OP = 'UPDATE' OR TG_OP = 'DELETE') THEN
     
    		-- Check if the sync tag exists
    		request := 'SELECT EXISTS(SELECT column_name FROM information_schema.columns WHERE table_name = ' ||
    			quote_literal(OLD.st_name) || ' AND column_name = ' || quote_literal(TAG_NAME) || ');';
    		EXECUTE request INTO tagged;
     
    		-- Drop the sync tag column
    		IF(tagged = TRUE) THEN
    			request := 'ALTER TABLE ' || quote_ident(OLD.st_name) || ' DROP ' || quote_ident(TAG_NAME) || ';';
    			EXECUTE request;
    		END IF;
     
    	END IF;
     
    	IF(TG_OP = 'INSERT' OR TG_OP = 'UPDATE') THEN
     
    		-- Check if the sync tag exists
    		request := 'SELECT EXISTS(SELECT column_name FROM information_schema.columns WHERE table_name = ' ||
    			quote_literal(NEW.st_name) || ' AND column_name = ' || quote_literal(TAG_NAME) || ');';
    		EXECUTE request INTO TAGGED;
     
    		-- Drop the sync tag column
    		IF(tagged = TRUE) THEN
    			request := 'ALTER TABLE ' || quote_ident(NEW.st_name) || ' DROP ' || quote_ident(TAG_NAME) || ';';
    			EXECUTE request;
    		END IF;
     
    		-- Add the sync tag column
    		request := 'ALTER TABLE ' || quote_ident(NEW.st_name) || ' ADD ' || quote_ident(TAG_NAME) || ' BOOLEAN;';
    		EXECUTE request;
    		-- Update previous rows with the sync tag to FALSE
    		request := 'UPDATE ' || quote_ident(NEW.st_name) || ' SET ' || quote_ident(TAG_NAME) || ' = FALSE;';
    		EXECUTE request;
    		-- Set the sync tag's default value to TRUE
    		request := 'ALTER TABLE ' || quote_ident(NEW.st_name) || ' ALTER ' || quote_ident(TAG_NAME) || ' SET DEFAULT TRUE';
    		EXECUTE request;
    		-- Set the sync tag NOT NULL
    		request := 'ALTER TABLE ' || quote_ident(NEW.st_name) || ' ALTER ' || quote_ident(TAG_NAME) || ' SET NOT NULL';
    		EXECUTE request;
     
    	END IF;
    	RETURN NULL;
    END;
    $diff_triggers_set$ LANGUAGE plpgsql;
     
    -- Trigger on sync tables to manage sync tags
    CREATE TRIGGER diff_triggers AFTER INSERT OR UPDATE OR DELETE ON sync_tables FOR EACH ROW EXECUTE PROCEDURE set_sync_tag();
    Si vous avez des suggestions sur le code ci-dessus, ou si vous connaissez un mécanisme plus efficace, n'hésitez pas.

  3. #3
    Inactif
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    245
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 245
    Points : 262
    Points
    262
    Par défaut
    Bonjour
    (sans faire de comparaisons).
    http://www.cis.upenn.edu/~bcpierce/unison/
    Je ne me souviens plus si il gère du (substring)
    Sinon il faut faire une VH et gérer 2 instances pour avoir
    2 bases différentes accessibles qui portent le même nom.
    Bon courage < unison > Bon courage

  4. #4
    Membre régulier
    Inscrit en
    Novembre 2003
    Messages
    245
    Détails du profil
    Informations forums :
    Inscription : Novembre 2003
    Messages : 245
    Points : 106
    Points
    106
    Par défaut
    Merci bustaf pour cette suggestion mais je ne pense pas que ce soit parfaitement adapté à mon utilisation.

    Pour perfectionner mon script ci-dessus, voyez-vous un moyen de détecter un DROP d'une table, afin de la supprimer de la liste des tables surveillées ("sync_tables") ? Ou bien un moyen de lier dynamiquement "sync_tables" et les tables surveillées, afin d'empêcher leur suppression ?

  5. #5
    Inactif
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    245
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 245
    Points : 262
    Points
    262
    Par défaut
    Bonjour
    Le drop peut être bloqué par le type d'utilisateur,il faut peut être voir les modes de debug ?
    Essayer d'enregistrer une traçabilité de charge pour ensuite la répercuter
    en différé de façon plus ou moins sélective ? je pense que cette approche n'est pas favorable pour vous et pour la base.
    Votre remarque:
    J'avais pensé déposer des triggers sur chaque table, et enregistrer pour chaque action, le nom de la table, et la valeur de chacun des identifiants. Hélas, c'est assez complexe de faire quelque chose de générique.

    Regardez si vous n'avez pas une approche de forme différente plus efficace

    Bon courage

Discussions similaires

  1. Réponses: 5
    Dernier message: 29/04/2014, 12h46
  2. [Débutant] inserer les modifications d'une datagrid dans la base données
    Par Invité dans le forum VB.NET
    Réponses: 4
    Dernier message: 14/03/2012, 14h28
  3. Tracer les modification dans une table Oracle
    Par shaun_the_sheep dans le forum Oracle
    Réponses: 3
    Dernier message: 21/09/2010, 11h48
  4. Réponses: 9
    Dernier message: 06/11/2007, 12h36
  5. gérer les jpg dans une fenetre directdraw???
    Par Anonymous dans le forum DirectX
    Réponses: 1
    Dernier message: 14/06/2002, 13h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo