H2 数据库 - "Unknown data type" 数据类型为空
H2 Database - "Unknown data type" with empty data type
我从 H2 收到一个非常奇怪的错误,它告诉我它不知道一种数据类型,但没有告诉我它是哪一种。
这是错误信息:
Unknown data type: ; SQL statement:
CREATE TABLE bans (id INT NOT NULL AUTO_INCREMENT, player_id INT NOT NULL, operator_id INT NOT NULL, end DATETIME NULL, reason VARCHAR(1024) NOT NULL, PRIMARY KEY (id), INDEX (player_id), INDEX (end), FOREIGN KEY (player_id) REFERENCES players(id), FOREIGN KEY (operator_id) REFERENCES players(id)) [50004-200]
这是 SQL 简单的查询:
CREATE TABLE bans (id INT NOT NULL AUTO_INCREMENT, player_id INT NOT NULL, operator_id INT NOT NULL, end DATETIME NULL, reason VARCHAR(1024) NOT NULL, PRIMARY KEY (id), INDEX (player_id), INDEX (end), FOREIGN KEY (player_id) REFERENCES players(id), FOREIGN KEY (operator_id) REFERENCES players(id))
我既不明白 H2 试图告诉我什么,也不明白该查询有什么问题。我尝试调整间距但无济于事。
编辑 1:
我正在用这个 JDBC 字符串打开数据库连接:
jdbc:h2:%s;AUTO_SERVER=%s;DATABASE_TO_UPPER=FALSE
(并使用 String.format
设置两个适当的值。第一个自然是基本文件名,第二个是 TRUE
或 FALSE
(都有效)。)
我不会更改任何其他设置或启用任何其他模式。我唯一做的就是之前创建 2 个表并向其中插入一些数据。
如果没有 MySQL 兼容模式,您不能在 H2 中使用非标准 INDEX(player_id)
和 INDEX(end)
。 (实际上数据库索引不在标准范围内。)
要么使用 MySQL 兼容模式,要么使用单独的 CREATE INDEX
命令,例如
CREATE INDEX ON bans(end);
不需要 player_id
列上的索引,因为 H2 会自动为约束 FOREIGN KEY (player_id) REFERENCES players(id)
.
创建非唯一索引
另请注意,DATABASE_TO_UPPER=FALSE
的行为自 1.4.198 以来已更改。使用此设置,所有列名都区分大小写。您可能想改用 DATABASE_TO_LOWER=TRUE
。
另一件需要注意的事情是列名称中的禁止字符。
例如如果您使用诸如 @Column(name="my-column")
之类的列名,那么您实际上会看到完全相同的错误消息。
Unknown data type: ; SQL statement:
当你真的卡住了时,连接到数据库的控制台网页,并尝试在那里执行查询。 (异常消息中通常会有查询)。
如果您 运行 一个嵌入式 H2 数据库,那么您可以通过设置以下属性来启用控制台网页:
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
# view database on http://localhost:8080/h2-console
spring.h2.console.enabled=true
有时当您在 H2 和您的开发数据库中具有相同的功能但功能不相同时,您会遇到此异常:
例如 H2 和 Orcacle 中的 CONVERT 函数。
在这种情况下,您可以在将其放入 H2 时覆盖 H2 函数 URL:BUILTIN_ALIAS_OVERRIDE=1;
然后你必须在你的测试资源中创建一个别名sql:
创建
“com.example.config.H2Functions.convert”的别名转换;
然后用 java 中的方法创建这个 class:
public class H2Functions {
public static String convert(String param1, String param2) {
return StringUtils.stripAccents(param1);
}}
如果您使用的是 Junit5,则必须实施 org.junit.jupiter.api.extension.BeforeEachCallback;
@Override
public void beforeEach(ExtensionContext context) throws Exception {
DataSource dataSource = getDataSource(context);
backupDatabase(dataSource);
}
private void backupDatabase(DataSource dataSource) {
try {
Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement();
RunScript.execute(connection, IOUtils.getReader(H2Extension.class.getResourceAsStream("/h2_functions.sql")));
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
并将这些注释放在你的测试中 class:
@SpringBootTest
@ExtendWith({SpringExtension.class, H2Extension.class})
我从 H2 收到一个非常奇怪的错误,它告诉我它不知道一种数据类型,但没有告诉我它是哪一种。
这是错误信息:
Unknown data type: ; SQL statement:
CREATE TABLE bans (id INT NOT NULL AUTO_INCREMENT, player_id INT NOT NULL, operator_id INT NOT NULL, end DATETIME NULL, reason VARCHAR(1024) NOT NULL, PRIMARY KEY (id), INDEX (player_id), INDEX (end), FOREIGN KEY (player_id) REFERENCES players(id), FOREIGN KEY (operator_id) REFERENCES players(id)) [50004-200]
这是 SQL 简单的查询:
CREATE TABLE bans (id INT NOT NULL AUTO_INCREMENT, player_id INT NOT NULL, operator_id INT NOT NULL, end DATETIME NULL, reason VARCHAR(1024) NOT NULL, PRIMARY KEY (id), INDEX (player_id), INDEX (end), FOREIGN KEY (player_id) REFERENCES players(id), FOREIGN KEY (operator_id) REFERENCES players(id))
我既不明白 H2 试图告诉我什么,也不明白该查询有什么问题。我尝试调整间距但无济于事。
编辑 1:
我正在用这个 JDBC 字符串打开数据库连接:
jdbc:h2:%s;AUTO_SERVER=%s;DATABASE_TO_UPPER=FALSE
(并使用 String.format
设置两个适当的值。第一个自然是基本文件名,第二个是 TRUE
或 FALSE
(都有效)。)
我不会更改任何其他设置或启用任何其他模式。我唯一做的就是之前创建 2 个表并向其中插入一些数据。
如果没有 MySQL 兼容模式,您不能在 H2 中使用非标准 INDEX(player_id)
和 INDEX(end)
。 (实际上数据库索引不在标准范围内。)
要么使用 MySQL 兼容模式,要么使用单独的 CREATE INDEX
命令,例如
CREATE INDEX ON bans(end);
不需要 player_id
列上的索引,因为 H2 会自动为约束 FOREIGN KEY (player_id) REFERENCES players(id)
.
另请注意,DATABASE_TO_UPPER=FALSE
的行为自 1.4.198 以来已更改。使用此设置,所有列名都区分大小写。您可能想改用 DATABASE_TO_LOWER=TRUE
。
另一件需要注意的事情是列名称中的禁止字符。
例如如果您使用诸如 @Column(name="my-column")
之类的列名,那么您实际上会看到完全相同的错误消息。
Unknown data type: ; SQL statement:
当你真的卡住了时,连接到数据库的控制台网页,并尝试在那里执行查询。 (异常消息中通常会有查询)。
如果您 运行 一个嵌入式 H2 数据库,那么您可以通过设置以下属性来启用控制台网页:
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
# view database on http://localhost:8080/h2-console
spring.h2.console.enabled=true
有时当您在 H2 和您的开发数据库中具有相同的功能但功能不相同时,您会遇到此异常:
例如 H2 和 Orcacle 中的 CONVERT 函数。
在这种情况下,您可以在将其放入 H2 时覆盖 H2 函数 URL:BUILTIN_ALIAS_OVERRIDE=1;
然后你必须在你的测试资源中创建一个别名sql:
创建 “com.example.config.H2Functions.convert”的别名转换;
然后用 java 中的方法创建这个 class:
public class H2Functions {
public static String convert(String param1, String param2) {
return StringUtils.stripAccents(param1);
}}
如果您使用的是 Junit5,则必须实施 org.junit.jupiter.api.extension.BeforeEachCallback;
@Override
public void beforeEach(ExtensionContext context) throws Exception {
DataSource dataSource = getDataSource(context);
backupDatabase(dataSource);
}
private void backupDatabase(DataSource dataSource) {
try {
Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement();
RunScript.execute(connection, IOUtils.getReader(H2Extension.class.getResourceAsStream("/h2_functions.sql")));
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
并将这些注释放在你的测试中 class:
@SpringBootTest
@ExtendWith({SpringExtension.class, H2Extension.class})