【问题标题】:H2 - How to create a database trigger that log a row change to another table?H2 - 如何创建将行更改记录到另一个表的数据库触发器?
【发布时间】:2015-07-11 15:57:59
【问题描述】:

如何创建一个数据库触发器,将行更改记录到 H2 中的另一个表?

在 MySQL 中,这很容易做到:

CREATE TRIGGER `trigger` BEFORE UPDATE ON `table`
  FOR EACH ROW BEGIN
    INSERT INTO `log`
    (
      `field1`
      `field2`,
      ...
    )
    VALUES
    (
      NEW.`field1`,
      NEW.`field2`,
      ...
    ) ;
    END;

【问题讨论】:

    标签: java sql triggers h2 jooq


    【解决方案1】:

    声明这个触发器:

    CREATE TRIGGER my_trigger
    BEFORE UPDATE
    ON my_table
    FOR EACH ROW
    CALL "com.example.MyTrigger"
    

    使用 Java/JDBC 实现触发器:

    public class MyTrigger implements Trigger {
    
        @Override
        public void init(Connection conn, String schemaName, 
                         String triggerName, String tableName, boolean before, int type)
        throws SQLException {}
    
        @Override
        public void fire(Connection conn, Object[] oldRow, Object[] newRow)
        throws SQLException {
            try (PreparedStatement stmt = conn.prepareStatement(
                "INSERT INTO log (field1, field2, ...) " +
                "VALUES (?, ?, ...)")
            ) {
                stmt.setObject(1, newRow[0]);
                stmt.setObject(2, newRow[1]);
                ...
    
                stmt.executeUpdate();
            }
        }
    
        @Override
        public void close() throws SQLException {}
    
        @Override
        public void remove() throws SQLException {}
    }
    

    用 jOOQ 实现触发器:

    由于您在问题中添加了 jOOQ 标记,我怀疑这个替代方案也可能是相关的。您当然可以在 H2 触发器中使用 jOOQ:

        @Override
        public void fire(Connection conn, Object[] oldRow, Object[] newRow)
        throws SQLException {
            DSL.using(conn)
               .insertInto(LOG, LOG.FIELD1, LOG.FIELD2, ...)
               .values(LOG.FIELD1.getDataType().convert(newRow[0]), 
                       LOG.FIELD2.getDataType().convert(newRow[1]), ...)
               .execute();
        }
    

    【讨论】:

      【解决方案2】:

      Lukas Eder 的简短回答:

      CREATE TRIGGER my_trigger
      BEFORE UPDATE
      ON my_table
      FOR EACH ROW
      CALL "com.example.MyTrigger"
      
      public class MyTrigger extends TriggerAdapter {
      
          @Override
          public void fire(Connection conn, ResultSet oldRow, ResultSet newRow) throws SQLException {
              // mannipulate the rows here by using the methods on the oldRow and newRow objects
          }
      }
      

      【讨论】:

      • 不错,但无法引用表格。
      猜你喜欢
      • 1970-01-01
      • 2021-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多