在 MODE=MySQL 中运行 h2 不支持 MySQL 转储
Posted
技术标签:
【中文标题】在 MODE=MySQL 中运行 h2 不支持 MySQL 转储【英文标题】:Running h2 in MODE=MySQL doesn't support MySQL dumps 【发布时间】:2013-01-24 20:00:34 【问题描述】:我正在尝试嵌入 h2 来测试我的 mysql 应用程序(集成测试)
我通过 maven 添加了 com.h2database:h2:1.3.170 并运行以下代码:
public class InMemoryTest
@Test
public void test() throws Exception
Class.forName("org.h2.Driver");
Connection conn = DriverManager.
getConnection("jdbc:h2:mem:test;MODE=MySQL;IGNORECASE=TRUE;INIT=RUNSCRIPT FROM 'src/test/resources/test.sql'");
这给了我以下例外:
Syntax error in SQL statement "
CREATE TABLE IF NOT EXISTS ""usr_avatar"" (
""usr_avatar_id"" INT(11) NOT NULL AUTO_INCREMENT,
""usr_avatar_user_id"" INT(11) NOT NULL,
""usr_avatar_img"" BLOB NOT NULL,
PRIMARY KEY (""usr_avatar_id""),
UNIQUE KEY ""usr_avatar_id_UNIQUE"" (""usr_avatar_id""),
UNIQUE KEY ""usr_avatar_user_id_UNIQUE"" (""usr_avatar_user_id""),
KEY ""usr_user_id"" (""usr_avatar_user_id""),
KEY ""fk_user_id"" (""usr_avatar_user_id"")
) AUTO_INCREMENT[*]=1 ";
显然,“AUTO_INCREMENT”导致了这个?
由于这是有效的 MySQL(我使用 MySQL Workbench 从我的真实数据库中导出了转储),我有点困惑,因为 h2 声称支持 MySQL? 以下是 .sql 中的几行:
DROP TABLE IF EXISTS `usr_avatar`;
CREATE TABLE IF NOT EXISTS "usr_avatar" (
"usr_avatar_id" int(11) NOT NULL AUTO_INCREMENT,
"usr_avatar_user_id" int(11) NOT NULL,
"usr_avatar_img" blob NOT NULL,
PRIMARY KEY ("usr_avatar_id"),
UNIQUE KEY "usr_avatar_id_UNIQUE" ("usr_avatar_id"),
UNIQUE KEY "usr_avatar_user_id_UNIQUE" ("usr_avatar_user_id"),
KEY "usr_user_id" ("usr_avatar_user_id"),
KEY "fk_user_id" ("usr_avatar_user_id")
) AUTO_INCREMENT=1 ;
DROP TABLE IF EXISTS `usr_restriction`;
CREATE TABLE IF NOT EXISTS "usr_restriction" (
"usr_restriction_id" int(11) NOT NULL AUTO_INCREMENT,
"usr_restriction_user_id" int(11) DEFAULT NULL,
"usr_restriction_ip" varchar(39) DEFAULT NULL,
"usr_restriction_valid_from" date NOT NULL,
"usr_restriction_valid_to" date DEFAULT NULL,
PRIMARY KEY ("usr_restriction_id"),
UNIQUE KEY "usr_restriction_id_UNIQUE" ("usr_restriction_id"),
KEY "user_id" ("usr_restriction_user_id"),
KEY "usr_user_id" ("usr_restriction_user_id")
) AUTO_INCREMENT=1 ;
我有哪些选择?我应该用不同的软件导出转储并强制它是纯 SQL 吗?哪个软件可以做到这一点?还是我做错了什么?
【问题讨论】:
【参考方案1】:问题是 H2 不支持你在 SQL 语句中指定的AUTO_INCREMENT=1
。尝试删除它。我认为 MySQL 也没有必要。
【讨论】:
感谢 Thomas 让我们有明确的答案!正如我之前所说,显然 h2 默认以 1 开头。也许值得在您的页面上提及应该使用哪些引号(显然是反引号或根本不使用引号),并且一次只能添加一个约束。非常感谢您在 h2 中投入的所有时间和精力——当涉及到内存集成测试时,这个数据库绝对是我的选择;-) 双引号和反引号不是问题:H2 支持它们。在SQL语句中实际发生错误的位置标有[*]
:错误信息为... AUTO_INCREMENT[*]=1 ...
【参考方案2】:
从 MySQL 导出的源 SQL 在其文字周围有双引号。第一个 DROP 语句还有一个“反引号”(`)。但是当 H2 报告错误时,H2 显示的是用双双引号括起来的文字。我认为这是问题所在。
尝试几件事。首先,在 DROP 语句中取反引号并将其转换为单引号。如果这不起作用,请将所有双引号转换为单引号。如果这不起作用,请删除所有引号。
我认为 H2 正在尝试使用双引号创建表作为实际表名/列名的一部分,这会导致它爆炸。
【讨论】:
感谢您的提示 - 反引号或从表名中删除引号/引号效果很好,而单引号/双引号引起了问题。尽管如此,“AUTO_INCREMENT=1;”仍然存在问题。在我桌子的尽头。但由于事实证明 h2 总是以值 1 开头,因此不需要这样做。 很好,我很高兴它成功了。老实说,AUTO_INCREMENT 修饰符不起作用并不让我感到惊讶。我认为 H2 没有针对 MySQL 特定行为的精确的一对一实现。但是 H2 确实具有 ALTER SEQUENCE 的能力,如果需要,您可以查看它。 谢谢!谈论 ALTER'ing 事物.. 添加约束时,一次只能添加一个。所以“ALTER TABLEa
ADD CONSTRAINT ... ; ALTER TABLE a
...”【参考方案3】:
H2 不支持AUTO_INCREMENT=1
。
改用这个:
ALTER TABLE table_name ALTER COLUMN id RESTART WITH 1;
【讨论】:
以上是关于在 MODE=MySQL 中运行 h2 不支持 MySQL 转储的主要内容,如果未能解决你的问题,请参考以下文章
Mysql SQL查询DATEDIFF在H2中失败,其中模式是MYSQL