【问题标题】:Spring Boot Database initialization MySQLException for TriggerSpring Boot数据库初始化MySQLException for Trigger
【发布时间】:2017-07-29 05:25:03
【问题描述】:

我正在使用带有 schema.sql 文件的 Spring JDBC 使用 Spring Boot 数据库初始化。我正在使用 MYSQL

如果我在 schema.sql 中有如下简单的表创建,它可以正常工作

CREATE TABLE Persons
(
PersonID int,
LastName varchar(255),
FirstName varchar(255),
Address varchar(255),
City varchar(255)
);

但是当我添加一个在 MySQL Workbench 中正确运行的触发器时

DROP TRIGGER IF EXISTS Persons_log_update; 

CREATE TRIGGER Persons_log_update 
    BEFORE UPDATE ON Persons
    FOR EACH ROW 
BEGIN

    INSERT INTO Personshistory(PersonID,LastName,FirstName,Address,City)
    values(OLD.PersonID,OLD.LastName,OLD.FirstName,OLD.Address,OLD.City);

END ^;

我用过 spring.datasource.separator=^;在属性文件中提到here

但它失败了,异常为

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CREATE TRIGGER Persons_log_update BEFORE UPDATE ON Persons FOR EACH ROW BE' at line 1

我想我的问题与this 的问题相同,但在 postgresql 中。

编辑: 如果我删除 spring.datasource.separator=^;来自属性文件并位于光标下方

DROP TRIGGER IF EXISTS Persons_log_update; 

DELIMITER $$
CREATE TRIGGER Persons_log_update 
    BEFORE UPDATE ON Persons
    FOR EACH ROW 
BEGIN

    INSERT INTO Personshistory(PersonID,LastName,FirstName,Address,City)
    values(OLD.PersonID,OLD.LastName,OLD.FirstName,OLD.Address,OLD.City);

END$$
DELIMITER ;

同样的错误

 com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER $$ CREATE TRIGGER Persons_log_update BEFORE UPDATE ON Persons FO' at line 1

【问题讨论】:

  • 您确定spring.datasource.separator=^ 不会替换您的分号作为分隔符吗?如果去掉这个属性配置会出现什么样的错误?
  • @Jagger 根据您的建议删除了 spring.datasource.separator=^ 但得到了类似的错误。检查更新的问题

标签: java mysql spring-boot sql-scripts


【解决方案1】:

当我在application.properties 中添加spring.datasource.separator=^; 并且程序/触发器之外的每一行都应以^; 终止时,我的问题得到了解决 示例如下:

DROP TRIGGER IF EXISTS Persons_log_update ^; 

CREATE TRIGGER Persons_log_update 
    BEFORE UPDATE ON Persons
    FOR EACH ROW 
BEGIN

    INSERT INTO Personshistory(PersonID,LastName,FirstName,Address,City)
    values(OLD.PersonID,OLD.LastName,OLD.FirstName,OLD.Address,OLD.City);

END ^;

【讨论】:

  • 这个答案拯救了我的日子!
【解决方案2】:

设置 spring.datasource.separator=^;没有解决我的问题。

我正在使用 ResourceDatabasePopulator 类加载 sql 脚本,发现这个类提供了设置分隔符的方法,所以我这样做了。

注意:dataSource 对象是自动装配的,由 spring 配置。所以在使用它之前添加它(javax.sql.DataSource)。

@Autowired DataSoruce 数据源

ResourceDatabasePopulator triggersPopulator = new ResourceDatabasePopulator(false, false, StandardCharsets.UTF_8.toString(), new ClassPathResource("triggers.sql"));
        triggersPopulator.setSeparator("//");
        triggersPopulator.execute(dataSource);

并根据分隔符 (//) 对 sql 脚本进行更改。

drop trigger if exists news_data_total_news_incremental_trigger;
//
create trigger news_data_total_news_incremental_trigger
after insert on `news_data` for each row
begin
declare cnt,newcnt bigint;
select `count` into cnt from `news_data_total_news` limit 1;
set newcnt = cnt + 1;
update `news_data_total_news` set `count` = newcnt where `count` = cnt;
end//

它奏效了。

还有一点,我们可以定义多个 ResourceDatabasePopulator 对象,并定义不同的分隔符。

ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator(false, false, StandardCharsets.UTF_8.toString(), new ClassPathResource("data.sql"));
        resourceDatabasePopulator.execute(dataSource);
        
ResourceDatabasePopulator triggersPopulator = new ResourceDatabasePopulator(false, false, StandardCharsets.UTF_8.toString(), new ClassPathResource("triggers.sql"));
        triggersPopulator.setSeparator("//");
        triggersPopulator.execute(dataSource);

如您所见,我有两个 ResourceDatabasePopulator 对象来加载两个不同的 sql 脚本,带有默认分隔符的 data.sql 和带有 // 作为分隔符的 triggers.sql。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-14
    • 2022-01-18
    • 2018-03-22
    • 2017-10-16
    • 2018-07-25
    • 1970-01-01
    • 2021-10-06
    • 2016-11-10
    相关资源
    最近更新 更多