23

H2 似乎在带引号的名称和不带引号的名称之间有所不同。有没有办法让它以同样的方式对待他们?

这是我所做的测试:

CREATE TABLE test (dummy INT);
CREATE TABLE "testquote" (dummy INT, "quotedDummy" INT);

以下是查询:

SELECT * FROM test; --work
SELECT * FROM "test"; -- doesn't work
SELECT * FROM "testquote"; --work
SELECT * FROM testquote; --doesn't work
SELECT dummy FROM "testquote"; --work
SELECT quotedDummy FROM "testquote"; --doesn't work
SELECT "quotedDummy" FROM "testquote"; --work

我该怎么做才能使这些查询与 H2 一起使用?

4

2 回答 2

38

根据 SQL 规范的要求,H2 中的引号名称区分大小写。这意味着这将起作用:

CREATE TABLE "testquote" (dummy INT, "quotedDummy" INT); 
SELECT * FROM "testquote";

但这不会:

SELECT * FROM "TestQuote";
SELECT * FROM "TESTQuote";
SELECT * FROM "TESTQUOTE";

Unquotes 名称在 H2 中不区分大小写。它们通常被转换为大写(如在 Oracle 和其他数据库中)。这意味着语句

CREATE TABLE test (dummy INT);
SELECT * FROM test;

是一样的

CREATE TABLE "TEST" ("DUMMY" INT);
SELECT * FROM "TEST";

因为 H2 的行为方式与 Oracle 相同。这与 MySQL 和 PostgreSQL 等其他数据库处理标识符名称的方式有些不同。H2 有一个兼容性特性:如果附加;DATABASE_TO_UPPER=FALSE到数据库 URL,取消引号标识符不会转换为大写,这意味着它们也区分大小写。但是您需要在创建数据库时附加它,并且每次使用它时(如果附加现有数据库的设置,现有对象的标识符已经转换为大写)。

顺便说一句,这与函数 UPPER无关,后者用于数据。您的问题是关于标识符,而不是数据。

于 2012-05-29T05:10:21.070 回答
0

我在使用 Hibernate 和 H2 时遇到了一些奇怪的问题,如果我在 @Table 注释中指定目录和模式名称,生成的 SQL 将对引用的表名使用错误的大小写,导致它失败。这可能是一个缺陷,但我找到了一个解决方法,我在这里分享。

import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;

public class H2IdentifierNamingStrategy extends PhysicalNamingStrategyStandardImpl {
    private static final long serialVersionUID = 1L;

    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
        if(name==null) return null;
        else return new Identifier(name.getText().toLowerCase(), name.isQuoted());
    }
}
于 2022-02-06T19:27:26.690 回答