HSQL 触发器生成 SQL 错误:-458,SQLState: S1000 / java.lang.ArrayIndexOutOfBoundsException

Posted

技术标签:

【中文标题】HSQL 触发器生成 SQL 错误:-458,SQLState: S1000 / java.lang.ArrayIndexOutOfBoundsException【英文标题】:HSQL Trigger generates SQL Error: -458, SQLState: S1000 / java.lang.ArrayIndexOutOfBoundsException 【发布时间】:2016-10-19 13:45:27 【问题描述】:

我有一个 HSQL 版本的 Oracle 数据库模式来执行单元测试。

我需要使用当前时间戳更新更新列。

我实现的触发器被 hsql 引擎加载而没有抱怨,但是当我尝试更新行时它在运行时崩溃。

这是一个示例测试用例,您可以在配置了 spring 和 junit 的项目中运行:

public class UtSqlTriggerTest 
    @Test public void testTrigger() throws SQLException 
        ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator();
        resourceDatabasePopulator.addScript(new InMemoryResource(
            "CREATE TABLE TEST (ID NUMERIC NOT NULL PRIMARY KEY,DATA VARCHAR(200), LAST_UPDATE TIMESTAMP);\n" +

             "CREATE TRIGGER updTimestamp AFTER UPDATE OF DATA ON TEST\n" +
             "REFERENCING NEW AS newrow OLD AS oldrow\n" +
             "FOR EACH ROW\n" +
             "SET newrow.LAST_UPDATE = current_timestamp;"));

        Connection connection = DriverManager.getConnection("jdbc:hsqldb:file:/opt/db/testdb;shutdown=true", "SA", "");
        resourceDatabasePopulator.populate(connection);

        JdbcTemplate tjdbc = new JdbcTemplate(new SingleConnectionDataSource(connection, true));
        tjdbc.update("INSERT INTO TEST(ID, DATA) VALUES (0, 'HELLO')");
        tjdbc.update("UPDATE TEST SET DATA = 'HELLO WORLD' WHERE ID = 0");
        tjdbc.queryForObject("SELECT LAST_UPDATE FROM TEST WHERE ID = 0", Date.class);
                   

这个触发器有什么问题?为什么会产生 ArrayIndexOutOfBoundException ?

CREATE TRIGGER updateDateAjoutFichier AFTER UPDATE OF DATA ON TEST
REFERENCING NEW AS newrow OLD AS oldrow
FOR EACH ROW
SET newrow.LAST_UPDATE = current_timestamp;

【问题讨论】:

【参考方案1】:

当您在 SQL 客户端中运行 CREATE TRIGGER 时,您将看到以下错误消息:

尝试分配给不可更新的列:LAST_UPDATE [SQL State=0U000, DB Errorcode=-2500]

这是因为您正在尝试修改 AFTER 触发器中的列。只有在BEFORE 触发器中才能更改列值。所以你应该使用:

CREATE TRIGGER updTimestamp BEFORE UPDATE OF DATA ON TEST
REFERENCING NEW AS newrow OLD AS oldrow
FOR EACH ROW
   SET newrow.LAST_UPDATE = current_timestamp;

【讨论】:

以上是关于HSQL 触发器生成 SQL 错误:-458,SQLState: S1000 / java.lang.ArrayIndexOutOfBoundsException的主要内容,如果未能解决你的问题,请参考以下文章

使用 SimpleJdbcTestUtils.executeSqlScript() 时 HSQLDB 触发语句错误

SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase] 错误

Mybatis运行错误:信息: SQLErrorCodes loaded: [DB2, Derby, H2, HDB, HSQL, Informix, MS-SQL, MySQL, Oracle, P

SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]

具有多个 when 子句的 HSQL 触发器

错误:无法生成 SQL Server 的用户实例