微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Oracle UNIQUE约束在不同情况下允许相同的值

如何解决Oracle UNIQUE约束在不同情况下允许相同的值

我对Oracle数据库表中的列具有UNIQUE约束。可以保存大小写相同的值。

例如; 首先,将 M100 插入表的UNIQUE列。再一次,当我尝试插入 M100 时,我可以看到唯一的违反约束错误

但是当我尝试插入 m100 时,数据库接受了此信息并将其保存到表中。

我该如何解决。无论情况如何,我都需要限制该值。

我正在使用以下版本

"Oracle Database 18c Express Edition Release 18.0.0.0.0 - Production
Version 18.4.0.0.0"

这里是Live SQL

解决方法

由于您使用的是Oracle 18,因此可以使用新功能,例如不可见列和虚拟列或collation

虚拟无形列+唯一约束: 例如,您有一个带有列STR的表T:

create table t(str varchar2(10));

因此,您可以添加以str_lower生成的不可见虚拟列lower(str)

alter table t add 
      str_lower varchar2(10) invisible generated always as (lower(str)) ;

由于此列是不可见的和虚拟的,因此不会破坏您现有的代码。 现在,您可以在其上添加unique约束:

alter table t add
      constraint t_str_unique_lower
         unique(str_lower) using index;

测试:

SQL> insert into t values('M100');

1 row created.

SQL> insert into t values('m100');
insert into t values('m100')
*
ERROR at line 1:
ORA-00001: unique constraint (XTENDER.T_STR_UNIQUE_LOWER) violated

此外,它还允许您通过较低的值轻松找到值:

SQL> select * from t where str_lower='m100';

STR
----------
M100

SQL> select str,str_lower from t where str_lower='m100';

STR        STR_LOWER
---------- ----------
M100       m100

如您所见,如果未在select-list中指定,则它不会返回str_lower列:

另一种可能的解决方案是为您的列指定collation ,但是需要将数据库参数MAX_STRING_SIZE设置为EXTENDED,否则您将获得{ {1}}

ORA-43929: Collation cannot be specified if parameter MAX_STRING_SIZE=STANDARD is set.

有关此的更多信息: https://oracle-base.com/articles/12c/column-level-collation-and-case-insensitive-database-12cr2

,

尝试将基于函数的索引添加到表中

CREATE UNIQUE INDEX some_index_name
ON tablename(UPPER(column_name));
,

先前的两个答案都很好,但是根据业务案例,还有另一种可能有意义的选择。有时您的数据不区分大小写(例如,电子邮件地址),因此请始终使用触发器将其存储在相同的大小写中。

然后,唯一约束将起作用,并且您的数据更干净。这样的触发器的一个示例是:

create or replace TRIGGER t_biu BEFORE
  INSERT OR UPDATE ON t
  FOR EACH ROW
DECLARE
BEGIN
  :NEW.column_name := UPPER(:NEW.column_name);
END t_biu;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。