如何在JdbcTemplate中创建mySQL存储过程

时间:2019-07-11 12:56:15

标签: java mysql spring jdbc jdbctemplate

背景

要解决MySql中的问题,即某些语句仅在我试图创建,运行然后在JdbcTemplate提交的sql中删除存储过程的存储过程中允许。一个简化的示例是(这恰好在春季启动中):

@Service
public class StartupDatabaseCheck {
    private JdbcTemplate template;

    @Autowired
    public StartupDatabaseCheck(JdbcTemplate template){
        this.template = template;
    }

    @PostConstruct
    public void init() {
        log.info("Running custom fields table creation (if required)");
        try {
            String migrateSql = Resources.toString(Resources.getResource("migrateScript.sql"), Charsets.UTF_8);
            template.execute(migrateSql);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
}

migrateScript.sql在哪里

DELIMITER //
CREATE PROCEDURE migrate()
BEGIN
    IF ((SELECT count(1)
         FROM INFORMATION_SCHEMA.COLUMNS
         WHERE table_name = 'custom_field_instance_data'
           and column_name='entity_id' and is_nullable = false) > 0)
    THEN
        alter table custom_field_instance_data MODIFY COLUMN entity_id char(32) null;
    END IF;
END //
DELIMITER ;

call migrate;

drop procedure migrate;

在mySql工作台中运行此程序可以正常工作,但由JdbcTemplate提交时出现错误

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 PROCEDURE migrate_custom_fields()

据我所知,这是因为这些DELIMITER语句are not permitted by JdbcTemplate但只是按照该链接中的建议将其删除会导致其他语法错误

问题

JdbcTemplate如何创建mySQL存储过程(或执行通常只允许存储过程使用的语句)

注释

没有deliminator语句的错误是

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 PROCEDURE migrate_custom_fields()

1 个答案:

答案 0 :(得分:1)

驱动程序似乎没有将定界查询带入帐户。如果要使用jdbc动态创建存储过程。 使用以下属性,并将其作为URL中的连接参数传递。

jdbc:mysql://localhost:3306/test?allowMultiQueries=true

以上属性将允许“;”分隔查询。 你可以在这里找到更多 Create MySQL stored procedure using JPA Hibernate

在这种情况下,更新后的migrateScript.sql将是

drop procedure IF EXISTS migrate_custom_fields;

CREATE PROCEDURE migrate_custom_fields()
BEGIN
    IF ((SELECT count(1)
         FROM INFORMATION_SCHEMA.COLUMNS
         WHERE table_name = 'custom_field_instance_data'
           and column_name='entity_id' and is_nullable = false) > 0)
    THEN
        alter table custom_field_instance_data MODIFY COLUMN entity_id char(32) null;
    END IF;
END ;

call migrate_custom_fields;

drop procedure migrate_custom_fields;