none
Ejecutar un script cada vez que una tabla sufre alguna modificación RRS feed

  • Pregunta

  • Hola,

    Me estoy iniciando en esto de las bases de datos y me ha surgido una duda que me gustaría poder llevar a cabo.

    Me gustaría que se lanzase un script hecho por mi en batch cada vez que UNA tabla de mi base de datos sufriera alguna modificación, ya sea actualizar un campo,  insertar un registro, etc...

    He investigado un poco pero no he encontrado nada... Espero que me puedan ayudar.

    Gracias!


    • Editado Sandritto jueves, 26 de julio de 2018 7:45
    jueves, 26 de julio de 2018 6:13

Respuestas

  • ¿Has investigado los triggers (desencadenadores)? Hay triggers de inserción, borrado y modificación, que se disparan respectivamente cuando haces el correspondiente cambio en la tabla. Los triggers contienen script consistente en sentencias SQL, donde puedes programar las operaciones deseadas.
    jueves, 26 de julio de 2018 11:54
  • Hola Sandrito:

    El escenario que te ha explicado Alberto Población perfectamente, implementado de un modo simple, puede ser tal que así:

    CREATE TABLE a1
    (id    INT IDENTITY(1, 1),
     valor VARCHAR(10)
    );
    GO
    CREATE TABLE auditoriaTablas
    (id       INT IDENTITY(1, 1) PRIMARY KEY,
     nomTabla VARCHAR(100),
     accion   VARCHAR(100),
     usuario  NVARCHAR(100),
     fecha    DATETIME
    );
    GO
    CREATE TRIGGER tr_a1_insert ON a1
    AFTER INSERT
    AS
         BEGIN
             INSERT INTO auditoriaTablas
    (nomTabla,
     accion,
     usuario,
     fecha
    )
             VALUES
    ('a1',
     'insertar',
     SUSER_NAME(),
     GETDATE()
    );
         END;
    GO
    CREATE TRIGGER tr_a1_Update ON a1
    AFTER UPDATE
    AS
         BEGIN
             INSERT INTO auditoriaTablas
    (nomTabla,
     accion,
     usuario,
     fecha
    )
             VALUES
    ('a1',
     'modificar',
     SUSER_NAME(),
     GETDATE()
    );
         END;
    GO
    CREATE TRIGGER tr_a1_Delete ON a1
    AFTER DELETE
    AS
         BEGIN
             INSERT INTO auditoriaTablas
    (nomTabla,
     accion,
     usuario,
     fecha
    )
             VALUES
    ('a1',
     'borrar',
     SUSER_NAME(),
     GETDATE()
    );
         END;
             INSERT INTO a1(valor)
             VALUES('LINEA2');
    GO
    SELECT *
    FROM auditoriaTablas;
    GO
    UPDATE a1
      SET
          valor = 'CAMBIO';
    GO
    SELECT *
    FROM auditoriaTablas;
    GO
    DELETE FROM a1;
    GO
    SELECT *
    FROM auditoriaTablas;

    Esto puede estar bien, pero cuando entra en producción, puede tener quebraderos de cabeza.

    Existen otros sistemas de auditoria, que quizás puedas evaluar.

    y por último y quizá el más interesante, el versionado de registros.

    Un saludo

    martes, 7 de agosto de 2018 16:30

Todas las respuestas

  • ¿Has investigado los triggers (desencadenadores)? Hay triggers de inserción, borrado y modificación, que se disparan respectivamente cuando haces el correspondiente cambio en la tabla. Los triggers contienen script consistente en sentencias SQL, donde puedes programar las operaciones deseadas.
    jueves, 26 de julio de 2018 11:54
  • Hola, he estado investigando y creo que un trigger es justo lo que necesito. Pero necesito saber qué fila se ha modificado/insertado y no consigo sacarlo. He leído bastante pero nada en claro. Gracias.
    martes, 7 de agosto de 2018 8:07
  • Dentro del trigger, se reciben dos pseudo-tablas que se llaman "inserted" y "deleted", y contienen respectivamente las filas que se han insertado o borrado.

    A estos efectos, el update lo trata como si hubiera sido un borrado seguido de una inserción, y por lo tanto en la tabla deleted trae los datos que había en la fila antes de modificarla, y en inserted trae los nuevos datos que se grabaron en la fila. Esto te permite saber de qué fila se trata.

    Ten presente que puede haber más de una fila en las tablas. Por ejemplo, si haces "update loquesea where campo=7", si hay 10 filas que tienen un 7 en ese campo entonces las tablas inserted y deleted tendrán esas 10 filas. No se dispara 10 veces el trigger con una fila cada vez, sino que se dispara una sola vez para todas las filas que se modificaron mediante una sola sentencia.

    martes, 7 de agosto de 2018 9:08
  • Hola Sandrito:

    El escenario que te ha explicado Alberto Población perfectamente, implementado de un modo simple, puede ser tal que así:

    CREATE TABLE a1
    (id    INT IDENTITY(1, 1),
     valor VARCHAR(10)
    );
    GO
    CREATE TABLE auditoriaTablas
    (id       INT IDENTITY(1, 1) PRIMARY KEY,
     nomTabla VARCHAR(100),
     accion   VARCHAR(100),
     usuario  NVARCHAR(100),
     fecha    DATETIME
    );
    GO
    CREATE TRIGGER tr_a1_insert ON a1
    AFTER INSERT
    AS
         BEGIN
             INSERT INTO auditoriaTablas
    (nomTabla,
     accion,
     usuario,
     fecha
    )
             VALUES
    ('a1',
     'insertar',
     SUSER_NAME(),
     GETDATE()
    );
         END;
    GO
    CREATE TRIGGER tr_a1_Update ON a1
    AFTER UPDATE
    AS
         BEGIN
             INSERT INTO auditoriaTablas
    (nomTabla,
     accion,
     usuario,
     fecha
    )
             VALUES
    ('a1',
     'modificar',
     SUSER_NAME(),
     GETDATE()
    );
         END;
    GO
    CREATE TRIGGER tr_a1_Delete ON a1
    AFTER DELETE
    AS
         BEGIN
             INSERT INTO auditoriaTablas
    (nomTabla,
     accion,
     usuario,
     fecha
    )
             VALUES
    ('a1',
     'borrar',
     SUSER_NAME(),
     GETDATE()
    );
         END;
             INSERT INTO a1(valor)
             VALUES('LINEA2');
    GO
    SELECT *
    FROM auditoriaTablas;
    GO
    UPDATE a1
      SET
          valor = 'CAMBIO';
    GO
    SELECT *
    FROM auditoriaTablas;
    GO
    DELETE FROM a1;
    GO
    SELECT *
    FROM auditoriaTablas;

    Esto puede estar bien, pero cuando entra en producción, puede tener quebraderos de cabeza.

    Existen otros sistemas de auditoria, que quizás puedas evaluar.

    y por último y quizá el más interesante, el versionado de registros.

    Un saludo

    martes, 7 de agosto de 2018 16:30