8

我尝试删除 h2 中列的唯一约束,之前创建为info varchar(255) unique.

我试过了:

sql> alter table public_partner drop constraint (select distinct unique_index_name from in
formation_schema.constraints where table_name='PUBLIC_PARTNER' and column_list='INFO');

但没有成功(如下):

Syntax error in SQL statement "ALTER TABLE PUBLIC_PARTNER DROP CONSTRAINT ([*]SELECT DISTI
NCT UNIQUE_INDEX_NAME FROM INFORMATION_SCHEMA.CONSTRAINTS WHERE TABLE_NAME='PUBLIC_PARTNER
' AND COLUMN_LIST='INFO') "; expected "identifier"; SQL statement:
alter table public_partner drop constraint (select distinct unique_index_name from informa
tion_schema.constraints where table_name='PUBLIC_PARTNER' and column_list='INFO') [42001-1
60]

如何正确删除此约束?

顺便一提:

sql> (select unique_index_name from information_schema.constraints where table_name='PUBLI
C_PARTNER' and column_list='INFO');
UNIQUE_INDEX_NAME
CONSTRAINT_F574_INDEX_9
(1 row, 0 ms)

似乎返回正确的输出。

4

3 回答 3

13

在 SQL 语言中,标识符名称不能是表达式。您需要运行两条语句:

select distinct constraint_name from information_schema.constraints 
where table_name='PUBLIC_PARTNER' and column_list='INFO'

然后获取标识符名称,并运行语句

ALTER TABLE PUBLIC_PARTNER DROP CONSTRAINT <xxx>
于 2012-04-04T17:20:45.663 回答
6

您可以使用用户定义的函数来执行动态创建的语句。首先创建execute别名(仅一次):

CREATE ALIAS IF NOT EXISTS EXECUTE AS $$ void executeSql(Connection conn, String sql) 
throws SQLException { conn.createStatement().executeUpdate(sql); } $$;

然后调用这个方法:

call execute('ALTER TABLE PUBLIC_PARTNER DROP CONSTRAINT ' || 
    (select distinct unique_index_name from in formation_schema.constraints 
    where table_name='PUBLIC_PARTNER' and column_list='INFO'));

...execute运行语句的用户定义函数在哪里。

于 2012-04-05T08:05:58.820 回答
1

如果您在PosgreSQL 模式下将 H2 与 Spring Boot 一起使用,则查询必须包含架构public,并且表可能处于小写模式。(见application.yml下文)

检查信息模式表中的字母大小写,并使用表中所示的大写和小写information_schema.constraints

详细查询集

SET @constraint_name = QUOTE_IDENT(
              SELECT DISTINCT constraint_name
              FROM information_schema.constraints
              WHERE table_schema = 'public'
              AND table_name = 'public_partner'
              AND constraint_type = 'UNIQUE'
              AND column_list = 'info');

SET @command = 'ALTER TABLE public.public_partner DROP CONSTRAINT public.' || @constraint_name;

SELECT @command;

EXECUTE IMMEDIATE @command;

解释:

  • SELECT DISTINCT 约束名 [...]

    从架构信息中选择具有唯一约束的列约束名称

  • QUOTE_IDENT([...])

    我不知道为什么需要这样做,它会引用结果字符串

  • SET @constraint_name = [...];

    存储在变量@constraint_name 中

  • SET @command = [...];

    通过串联字符串组成整个命令并存储在变量@command

  • 选择@命令;

    在屏幕上显示组合查询,仅用于调试

  • 立即执行@command;

    执行@command

Spring Boot中PostgreSQL 模式下的典型 H2 配置application.yml(摘录)

spring:
  # [...]
  jpa:
    database-platform: org.hibernate.dialect.H2Dialect
  # [...]
  datasource:
    url: jdbc:h2:mem:testdb;MODE=PostgreSQL;DATABASE_TO_LOWER=TRUE;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false
    username: sa
    password: sa
  # [...]
于 2020-09-04T07:36:48.657 回答