Spring Boot数据库初始化MySQLException for Trigger

时间:2017-03-08 15:03:14

标签: java mysql spring-boot sql-scripts

我使用Spring JDBC数据库初始化使用Spring JDBC和schema.sql文件。我正在使用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

2 个答案:

答案 0 :(得分:2)

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

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 ^;

答案 1 :(得分:0)

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

我正在使用ResourceDatabasePopulator类加载sql脚本,发现该类提供了设置Separator的方法,所以我做到了。

注意: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。