gpt4 book ai didi

jdbc - H2 - CREATE TABLE 创建了错误的数据类型

转载 作者:行者123 更新时间:2023-12-04 03:13:48 24 4
gpt4 key购买 nike

使用 H2 内存数据库测试我的 DAL 当前不起作用,因为数据类型 BINARY 被转换为 VARBINARY:

CREATE TABLE test (
pk_user_id INT AUTO_INCREMENT(1, 1) PRIMARY KEY,
uuid BINARY(16) UNIQUE NOT NULL
);

如果我检查具有预期数据类型的列是否存在,这会导致错误的数据类型:

2017-03-20 16:24:48 persistence.database.Table check Unexpected column (UUID) or type (-3, VARBINARY)

最佳答案

tl;dr

which results in a wrong data type

不,不是错误类型,只是相同类型的另一个标签

二进制类型有五个同义词:{ BINARY |变量 |长二进制 |原始 |字节跳动

所有五个名字的意思是the same type , 并且都映射到 Java 中的 byte[]

数据类型名称的同义词

数据类型在 SQL 世界中没有严格定义。 SQL 规范只定义了几种类型。许多数据库系统通过许多名称定义许多类型。为了使客户更容易从一个数据库系统移植到他们的数据库系统,数据库供应商通常为数据类型实现同义词,以匹配类型兼容的竞争对手的数据类型。

与许多其他数据库系统一样,H2 对一种数据类型有多个名称。对于将整个值加载到内存中的二进制类型,H2 为相同的单一数据类型定义了五个名称:

{ BINARY | VARBINARY | LONGVARBINARY | RAW | BYTEA }

类似地,H2 通过五个同义词中的任何一个提供了一个带符号的 32 位整数数据类型:

{ INT | INTEGER | MEDIUMINT | INT4 | SIGNED }

因此您可以指定这五个名称中的任何一个,但您将获得相同的效果,即 H2 提供的相同基础数据类型。

事实上,我自己运行代码来使用二进制类型的这五个名称中的每一个来创建列。在每种情况下,列名的元数据都将数据类型报告为 VARBINARY

虽然在内部使用这五个中的哪一个来跟踪列的数据类型并不重要,但我对 VARBINARY 的使用感到有点惊讶,因为 H2 datatype documentation page heading 将此类型宣传为 BINARY。所以我希望在元数据中默认使用 BINARY。如果您真的很在意,您可能想为此记录一个错误/问题,因为似乎文档标题应该更改为 VARBINARY 或者 H2 的内部数据类型标签应该更改为 BINARY

下面是一些示例 Java JDBC 代码,用于确认您在问题中报告的行为。

我建议您更改数据类型检查代码以查找此数据类型的五个可能名称中的任何,而不是仅检查一个特定名称。

try {
Class.forName ( "org.h2.Driver" );
} catch ( ClassNotFoundException e ) {
e.printStackTrace ( );
}
try ( Connection conn = DriverManager.getConnection ( "jdbc:h2:mem:" ) ;
Statement stmt = conn.createStatement ( ) ; ) {
String tableName = "test_";
String sql = "CREATE TABLE " + tableName + " (\n" +
" pk_user_id_ INT AUTO_INCREMENT(1, 1) PRIMARY KEY,\n" +
" uuid_ BINARY(16) UNIQUE NOT NULL\n" +
");";
// String sql = "CREATE TABLE " + tableName +
// "(" +
// " id_ INT AUTO_INCREMENT(1, 1) PRIMARY KEY, " +
// " binary_id_ BINARY(16) UNIQUE NOT NULL, " +
// " uuid_id_ UUID, " +
// " age_ INTEGER " + ")";
stmt.execute ( sql );

// List tables
DatabaseMetaData md = conn.getMetaData ( );
try ( ResultSet rs = md.getTables ( null, null, null, null ) ) {
while ( rs.next ( ) ) {
System.out.println ( rs.getString ( 3 ) );
}
}

// List columns of our table.
try ( ResultSet rs = md.getColumns ( null, null, tableName.toUpperCase ( Locale.US ), null ) ) {
System.out.println ( "Columns of table: " + tableName );
while ( rs.next ( ) ) {
System.out.println ( rs.getString ( 4 ) + " | " + rs.getString ( 5 ) + " | " + rs.getString ( 6 ) ); // COLUMN_NAME, DATA_TYPE , TYPE_NAME.
}
}
} catch ( SQLException e ) {
e.printStackTrace ( );
}

CATALOGS

COLLATIONS

USERS

VIEWS

TEST_

Columns of table: test_

PK_USER_ID_ | 4 | INTEGER

UUID_ | -3 | VARBINARY

提示:

  • 在您的所有 SQL 名称中添加尾随下划线可避免与 SQL 世界中超过一千个保留字中的任何一个发生冲突。 SQL 规范 promise SQL 系统永远不会使用结尾的下划线。例如,您使用列名 uuid 可能会与 H2 的 UUID 数据类型冲突。
  • 您的代码 uuid BINARY(16) 表明您正在尝试存储 UUID (一个 128 位值,其中一些位定义了语义)。注意 H2 supports UUID natively作为数据类型 as does Postgres和其他一些数据库系统。因此,将 uuid_ BINARY(16) 更改为 uuid_ UUID

关于jdbc - H2 - CREATE TABLE 创建了错误的数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42907617/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com