Oracle中不区分大小写的主键

Posted

技术标签:

【中文标题】Oracle中不区分大小写的主键【英文标题】:Case-insensitive primary key in Oracle 【发布时间】:2011-11-02 16:58:32 【问题描述】:

我们的数据语义不区分大小写,因此我们将 oracle 会话配置为不区分大小写:

alter session set NLS_COMP=LINGUISTIC;
alter session set NLS_SORT=BINARY_AI;

然后,为了利用索引,我们还希望主键不区分大小写:

create table SCHEMA_PROPERTY (
  NAME  nvarchar2(64)   not null,
  VALUE nvarchar2(1024),
  constraint SP_PK primary key (nlssort(NAME))
)

但是,这会遇到“ORA-00904: : invalid identifier”,所以我认为不可能在 PK 定义中使用 nlssort() 函数。

下一个尝试是将不区分大小写的唯一索引与主键相关联:

create table SCHEMA_PROPERTY (
  NAME  nvarchar2(64) primary key using index (
      create unique index SP_UQ on SCHEMA_PROPERTY(nlssort(NAME))),
  VALUE nvarchar2(1024)
);

但这也失败了:

Error: ORA-14196: Specified index cannot be used to enforce the constraint.
14196. 00000 -  "Specified index cannot be used to enforce the constraint."
*Cause:    The index specified to enforce the constraint is unsuitable
           for the purpose.
*Action:   Specify a suitable index or allow one to be built automatically.

我是否应该得出结论,Oracle 不支持 PK 约束的不区分大小写的语义?这在 MSSQL 中运行良好,它在处理排序规则方面具有更简单的方法。

当然,我们可以创建唯一索引而不是主键,但我想首先确保不支持执行此操作的常规方法。

我们的 oracle 版本是 11.2.0.1。

【问题讨论】:

【参考方案1】:

在 11.2 上,您可以使用虚拟列来实现此目的:

CREATE TABLE SCHEMA_PROPERTY (
   REAL_NAME  nvarchar2(64) not null,
   NAME       generated always as (lower(real_name)) primary key,
   VALUE nvarchar2(1024)
);

【讨论】:

lower() 和 nlssort() 之间没有区别。我的帖子的重点是,似乎不可能基于函数定义 PK。 PK只能基于实际列。 @BogdanCalmac:你是对的,抱歉应该在发帖前测试一下。使用 11.x 有一个解决方法,请参阅我的编辑 我们还必须支持 Oracle 10g,但即使没有它,它看起来也比使用唯一索引而不是主键更难看。 @BogdanCalmac:如果您可以使用唯一索引,那么可以使用它!我认为您需要 PK 定义才能为该表创建外键。【参考方案2】:

创建唯一索引以强制执行不区分大小写的 PK:

create table SCHEMA_PROPERTY (
  NAME  nvarchar2(64),
  VALUE nvarchar2(1024),
  constraint SP_PK primary key (NAME)
);

create unique index SP_UN on SCHEMA_PROPERTY(lower(NAME));

【讨论】:

以上是关于Oracle中不区分大小写的主键的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 对主键区分大小写

在oracle中不区分大小写的顺序

SQL语句中模糊查询中不区分大小写怎么写?如:select × from table where number like‘%PK%’

Java UUID是不是区分大小写

Java UUID是不是区分大小写

Java UUID是不是区分大小写