行继续Spring SQL ScriptUtils(使用H2)

Uel*_*ter 7 java sql spring jdbc h2

我有以下SQL脚本(initDB.sql)

CREATE TABLE  FFShareHistorical  (  ID int NOT NULL AUTO_INCREMENT,
                                    PX_LAST  Double DEFAULT NULL, 
                                    PX_OPEN  Double DEFAULT NULL, 
                                    PX_HIGH  Double DEFAULT NULL, 
                                    PX_LOW  Double DEFAULT NULL, 
                                    PRIMARY KEY (ID))
Run Code Online (Sandbox Code Playgroud)

并希望使用Spring的ScriptUtils(4.1.4.RELEASE)执行它,即

Resource rc = new ClassPathResource("initDB.sql");
ScriptUtils.executeSqlScript(dataSource.getConnection(), rc);
Run Code Online (Sandbox Code Playgroud)

问题是看起来断行被解释为SQL语句的终止,即错误堆栈跟踪看起来像这样

org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement at line 1 of resource class path resource [initDB.sql]: CREATE TABLE FFShareHistorical ( ID int NOT NULL AUTO_INCREMENT, ; nested exception is org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "CREATE TABLE FFSHAREHISTORICAL ( ID INT NOT NULL AUTO_INCREMENT,  "; expected "identifier"; SQL statement:
CREATE TABLE FFShareHistorical ( ID int NOT NULL AUTO_INCREMENT,  [42001-176]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:344)
    at org.h2.message.DbException.getSyntaxError(DbException.java:204)
    at org.h2.command.Parser.readColumnIdentifier(Parser.java:3068)
    at org.h2.command.Parser.parseCreateTable(Parser.java:5722)
    at org.h2.command.Parser.parseCreate(Parser.java:4122)
    at org.h2.command.Parser.parsePrepared(Parser.java:351)
    at org.h2.command.Parser.parse(Parser.java:306)
    at org.h2.command.Parser.parse(Parser.java:278)
    at org.h2.command.Parser.prepareCommand(Parser.java:243)
    at org.h2.engine.Session.prepareLocal(Session.java:442)
    at org.h2.server.TcpServerThread.process(TcpServerThread.java:265)
    at org.h2.server.TcpServerThread.run(TcpServerThread.java:160)
    at java.lang.Thread.run(Unknown Source)

    at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:475)
    at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:393)
    at org.springframework.jdbc.datasource.init.ScriptUtils.executeSqlScript(ScriptUtils.java:372)
    at ch.qpmlib.flatfiledatabase.jdbc.dao.FFDBSetup.setupDB(FFDBSetup.java:26)
    at ch.qpmlib.flatfiledatabase.jdbc.main.SpringMain.setupDB(SpringMain.java:30)
    at ch.qpmlib.flatfiledatabase.jdbc.main.SpringMain.main(SpringMain.java:17)
Caused by: org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "CREATE TABLE FFSHAREHISTORICAL ( ID INT NOT NULL AUTO_INCREMENT,  "; expected "identifier"; SQL statement:
CREATE TABLE FFShareHistorical ( ID int NOT NULL AUTO_INCREMENT,  [42001-176]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:344)
    at org.h2.message.DbException.getSyntaxError(DbException.java:204)
    at org.h2.command.Parser.readColumnIdentifier(Parser.java:3068)
    at org.h2.command.Parser.parseCreateTable(Parser.java:5722)
    at org.h2.command.Parser.parseCreate(Parser.java:4122)
    at org.h2.command.Parser.parsePrepared(Parser.java:351)
    at org.h2.command.Parser.parse(Parser.java:306)
    at org.h2.command.Parser.parse(Parser.java:278)
    at org.h2.command.Parser.prepareCommand(Parser.java:243)
    at org.h2.engine.Session.prepareLocal(Session.java:442)
    at org.h2.server.TcpServerThread.process(TcpServerThread.java:265)
    at org.h2.server.TcpServerThread.run(TcpServerThread.java:160)
    at java.lang.Thread.run(Unknown Source)
Run Code Online (Sandbox Code Playgroud)

所以问题是,如何将ScriptUtils与多行SQL脚本一起使用?特别是我正在寻找一些我可以添加到脚本中的"行继续"字符或者告诉Spring的ScriptUtils删除所有换行符的方法.

Uel*_*ter 7

事实证明,使用多行语句没有问题.但是,如果语句没有以";"结束,那么ScriptUtils将回退到使用"\n"作为分隔符.所以在这种情况下,只需使用";"来终止脚本 即

CREATE TABLE  FFShareHistorical  (  ID int NOT NULL AUTO_INCREMENT,
                                    PX_LAST  Double DEFAULT NULL, 
                                    PX_OPEN  Double DEFAULT NULL, 
                                    PX_HIGH  Double DEFAULT NULL, 
                                    PX_LOW  Double DEFAULT NULL, 
                                    PRIMARY KEY (ID));
Run Code Online (Sandbox Code Playgroud)

会做的.


Ale*_*kov 5

您的存档中有文档。查看以下位置:

  • spring-framework-4.1.4.RELEASE-dist / spring-framework-4.1.4.RELEASE / docs / javadoc-api / org / springframework / jdbc / datasource / init /
  • spring-framework-4.1.4.RELEASE-dist / spring-framework-4.1.4.RELEASE / docs / spring-framework-reference /

executeSqlScript(...)内部使用A方法ResourceDatabasePopulator 执行SQL脚本。

ResourceDatabasePopulator 提供了一个简单的基于对象的API,可使用外部资源中定义的SQL脚本以编程方式填充,初始化或清理数据库。

ResourceDatabasePopulator 提供配置选项-

  • 字符编码
  • 语句分隔符
  • 注释定界符
  • 解析和执行脚本时使用的错误处理标志

每个配置选项都有一个默认值

SQL脚本中的默认语句分隔符设置为";"

也:

  • static void executeSqlScript(Connection connection, EncodedResource resource) 使用语句分隔符,注释定界符和异常处理标志的默认设置执行给定的SQL脚本。

  • static void executeSqlScript(Connection connection, EncodedResource resource, boolean continueOnError, boolean ignoreFailedDrops, String commentPrefix, String separator, String blockCommentStartDelimiter, String blockCommentEndDelimiter) 执行给定的SQL脚本。

  • static void executeSqlScript(Connection connection, Resource resource) 使用语句分隔符,注释定界符和异常处理标志的默认设置执行给定的SQL脚本。


但是,有一个回退机制,"\n"可以";"在整个脚本中没有回退机制。有关更多详细信息,请参见@chuchikaeschtli答案。