简体   繁体   English

Informix数据库中的条件唯一约束

[英]Conditional unique constraint in an Informix DB

Is it possible to create conditional unique constraints in an informix db (my current version is 11.70) 是否可以在informix数据库中创建条件唯一约束(我的当前版本是11.70)

Example of what I would like to do (postgresql): 我想做的事示例(postgresql):

create table test (id int primary key, v varchar(25), a boolean);
create unique index test_index on test(v, a) where a = true;

insert into test values (1, 'l', true);
insert into test values (2, 'k', true);
insert into test values (3, 'l', false);
insert into test values (4, 'l', false);
insert into test values (5, 'l', true); -- Fails because of test_index

select * from test;
-- prints:
-- id   v   a
-- --------------
-- 1    l   true
-- 2    k   true
-- 3    l   false
-- 4    l   false

For what I understand you want v to be unique only if a is true . 据我了解,您希望v仅在atrue时才是唯一的。

Although you can't create a unique index you can create a trigger over the DML operation to achive this. 尽管无法创建唯一索引,但是可以在DML操作上创建触发器以实现此目的。

Example for the INSERT operation: INSERT操作的示例:

[infx1150@tardis ~]$ dbaccess test -

Database selected.

> CREATE TABLE test (
>       id      INT PRIMARY KEY,
>       v       VARCHAR(25),
>       a       BOOLEAN
> );

Table created.

> CREATE PROCEDURE sp_test(v_val VARCHAR(25), a_val BOOLEAN)
>       DEFINE n INT;
>       LET n = 0;
>
>       IF a_val THEN
>               SELECT COUNT(*) INTO n
>               FROM test
>               WHERE v = v_val
>               AND a = 't';
>
>               IF n > 1 THEN
>                       RAISE EXCEPTION -746, 0, "There is already one row with v = " || v_val || " and a true flag";
>               END IF;
>       END IF;
> END PROCEDURE;

Routine created.

> CREATE TRIGGER ti_test INSERT ON test
>       REFERENCING new AS n
>       FOR EACH ROW (EXECUTE PROCEDURE sp_test(n.v, n.a));

Trigger created.

> INSERT INTO test VALUES (1, 'l', 't');

1 row(s) inserted.

> INSERT INTO test VALUES (2, 'k', 't');

1 row(s) inserted.

> INSERT INTO test VALUES (3, 'l', 'f');

1 row(s) inserted.

> INSERT INTO test VALUES (4, 'l', 'f');

1 row(s) inserted.

> INSERT INTO test VALUES (5, 'l', 't');

  746: There is already one row with v = l and a true flag
Error in line 1
Near character position 1
> SELECT * FROM test;


         id v                         a

          1 l                         t
          2 k                         t
          3 l                         f
          4 l                         f

4 row(s) retrieved.

>

Database closed.

[infx1150@tardis ~]$

This will work in a database with transaction logging ( buffered , unbuffered and ANSI ) but not on a non transaction database. 这将在具有事务日志记录缓冲无缓冲ANSI )的数据库中工作,但不适用于非事务数据库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM