如何使MySQL数据库模式与H2数据库兼容

8

我目前使用mysql作为我的数据库,并使用flyway来管理数据库模式。所有的单元测试都在mysql上运行,随着添加更多的单元测试,它们运行得非常缓慢。现在我想在单元测试中将数据库从mysql更改为h2内存数据库。以下是我的h2 db连接设置:

#Datasource
spring.datasource.url=jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE;DATABASE_TO_UPPER=true
spring.datasource.username=
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.default-transaction-isolation-level=1

当我运行flywayMigrate时,我遇到了一些SQL错误。以下是一个例子,这个SQL用于在MySQL上创建表,但在h2上无法运行。

CREATE TABLE `file_storage` (
  `id` BIGINT(64) NOT NULL AUTO_INCREMENT,
  `file_name` VARCHAR(45) NULL,
  PRIMARY KEY (`id`))
DEFAULT CHARACTER SET = utf8;

以下是我从h2得到的错误。我不知道我的sql有什么问题。是否有一种方法让h2接受mysql数据库模式?

Execution failed for task ':dbschema:flywayMigrate'.
> Error occurred while executing flywayMigrate

  Migration V2016_02_26_12_59__create_file_storage.sql failed
  -----------------------------------------------------------
  SQL State  : 42000
  Error Code : 42000
  Message    : Syntax error in SQL statement "CREATE TABLE ""FILE_STORAGE"" (
    ""ID"" BIGINT(64) NOT NULL AUTO_INCREMENT,
    ""FILE_NAME"" VARCHAR(45) NULL,
    PRIMARY KEY (""ID""))
  DEFAULT CHARACTER[*] SET = UTF8 "; SQL statement:
  CREATE TABLE `file_storage` (
    `id` BIGINT(64) NOT NULL AUTO_INCREMENT,
    `file_name` VARCHAR(45) NULL,
    PRIMARY KEY (`id`))
  DEFAULT CHARACTER SET = utf8 [42000-190]
  Location   : db/migration/V2016_02_26_12_59__create_file_storage.sql (/Users/yzzhao/dev/cooltoo/cooltoo_backend/dbschema/build/resources/main/db/migration/V2016_02_26_12_59__create_file_storage.sql)
  Line       : 1
  Statement  : CREATE TABLE `file_storage` (
    `id` BIGINT(64) NOT NULL AUTO_INCREMENT,
    `file_name` VARCHAR(45) NULL,
    PRIMARY KEY (`id`))
  DEFAULT CHARACTER SET = utf8

  Syntax error in SQL statement "CREATE TABLE ""FILE_STORAGE"" (
    ""ID"" BIGINT(64) NOT NULL AUTO_INCREMENT,
    ""FILE_NAME"" VARCHAR(45) NULL,
    PRIMARY KEY (""ID""))
  DEFAULT CHARACTER[*] SET = UTF8 "; SQL statement:
  CREATE TABLE `file_storage` (
    `id` BIGINT(64) NOT NULL AUTO_INCREMENT,
    `file_name` VARCHAR(45) NULL,
    PRIMARY KEY (`id`))
  DEFAULT CHARACTER SET = utf8 [42000-190]

编辑

我有数百个在mysql中正常运行的sql脚本。因此,我不想更改这些脚本中的任何内容。有没有一种方法允许h2接受mysql脚本?


替换或删除 ; 或尝试使用 http://topnew.net/sidu 点击表描述,然后复制粘贴创建表 SQL,在不需要时不要使用 `。 - SIDU
我尝试去掉所有的反引号(`),但出现了“SQL语法错误”的错误。我有超过一百个SQL脚本,不想一个一个地修改它们。所有这些SQL在MySQL中都能正常工作。因此,我想知道是否有一种方法可以配置h2数据库以接受这些语法。 - Joey Yi Zhao
2个回答

7
根据这个描述,您可以尝试在连接字符串中设置MODE=MySQL,以在MySQL兼容模式下使用H2数据库。以下是具体说明:
引用:

要使用MySQL模式,请使用数据库URL jdbc:h2:~/test;MODE=MySQL或SQL语句SET MODE MySQL

  • 插入数据时,如果一个列被定义为NOT NULL,并且插入了NULL,则使用0(或空字符串,或时间戳列的当前时间)值。通常,此操作是不允许的,会抛出异常。

  • CREATE TABLE语句中创建索引可以使用INDEX(..)KEY(..)。例如:create table test(id int primary key, name varchar(255), key idx_name(name));

  • 元数据调用以小写形式返回标识符。

  • 将浮点数转换为整数时,不截断小数位,而是四舍五入。

  • NULL与另一个值连接会得到另一个值。

在MySQL中,文本比较默认是不区分大小写的,而在H2中是区分大小写的(与大多数其他数据库一样)。 H2确实支持不区分大小写的文本比较,但需要单独设置,使用SET IGNORECASE TRUE。这会影响使用=LIKEREGEXP进行比较。


2
在描述中看起来很棒。根据我的经验,如果不重新制作,它是无法正常工作的。 - Daniel Käfer
这个部分有效。如果你有“简单”的.sql文件,一切都会很好。但是如果你有更复杂的语句,它就不能像应该那样工作。 - sayil aguirre

4

您的问题可以从您的示例中看出。

CREATE TABLE `file_storage`
(
   'id` BIGINT(64) NOT NULL AUTO_INCREMENT, 
   `file_name` VARCHAR(45) NULL, 
   PRIMARY KEY (`id`)
)
DEFAULT CHARACTER SET = utf8;

最后一行“DEFAULT CHARACTER SET = utf8”是设置mySQL表选项的。H2没有这样的选项,因为它始终使用Unicode。

如果你有很多多年前为MySQL编写的SQL DDL语句,你可能会遇到很多这样的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接