[英]DEFERRABLE INITIALLY DEFERRED on index contraint in postgresql
我可以使用以下查询添加DEFERRABLE INITIALIALDEFERED:
ALTER TABLE user DROP CONSTRAINT unq_user_address, add CONSTRAINT unq_user_address UNIQUE(user_address) deferrable INITIALLY DEFERRED;
现在,我还有另一列,我想添加DEFERRABLE INITIALIALLY DEFERRED。 约束是在索引上的,所以我这样做时会出错。
这是索引约束:
CREATE UNIQUE INDEX unq_account
ON user
USING btree
(lower(account::text) COLLATE pg_catalog."default");
我修改为说
CREATE UNIQUE INDEX unq_account
ON user
USING btree
(lower(account::text) COLLATE pg_catalog."default") deferrable INITIALLY DEFERRED;
也尝试过
CREATE UNIQUE INDEX unq_account
ON user
USING btree
(lower(account::text) COLLATE pg_catalog."default") UNIQUE_CHECK_PARTIAL;
因此,不知道如何在索引上应用相同的内容。
我看到以下官方文档: https : //www.postgresql.org/docs/9.6/static/index-unique-checks.html
UNIQUE_CHECK_PARTIAL表示唯一约束是可延迟的。 PostgreSQL将使用此模式插入每一行的索引条目。 访问方法必须允许重复的条目进入索引,并通过从aminsert返回FALSE来报告任何潜在的重复。 对于返回FALSE的每一行,将安排一次延迟的重新检查。
和这里:
UNIQUE_CHECK_EXISTING表示这是对报告为潜在唯一性违规的行的重新检查。 尽管这是通过调用aminsert来实现的,但是在这种情况下,访问方法不得插入新的索引条目。 索引条目已经存在。 而是,访问方法必须检查以查看是否还有另一个活动索引条目。 如果是这样,并且目标行也仍然存在,请报告错误。
是我需要使用的东西吗?如果是,那么如何使用?
您不能将索引定义为可递延索引。 可延迟性是约束的属性,而不是索引。
CREATE TABLE test_table
(
test_col integer not null
);
ALTER TABLE test_table
ADD constraint test_col_unique unique (test_col) deferrable initially deferred;
但是,不能将任意表达式用于唯一约束,只能使用直接列引用:
ALTER TABLE test_table
ADD CONSTRAINT test_col_abs_unique UNIQUE (abs(test_col));
将报告
ERROR: syntax error at or near "("
因为解析器仅处理简单的列引用。
因此,您不能将这张支票延期。
您不能在CREATE INDEX ...
SQL查询中使用UNIQUE_CHECK_PARTIAL
, UNIQUE_CHECK_EXISTING
。 就像您在“ 访问方法接口”文档页面上所说的那样,
...向aminsert函数传递了一个checkUnique参数,该参数具有以下值之一:UNIQUE_CHECK_NO ...,UNIQUE_CHECK_YES ...,UNIQUE_CHECK_PARTIAL ...,UNIQUE_CHECK_EXISTING
因此,这些是要传递给aminsert函数的 checkUnique参数的值(我认为这是访问方法接口API或内部的一部分)
其余的由克雷格回答。
您可以alter table "user" add CONSTRAINT unq_user_address UNIQUE(account) deferrable INITIALLY DEFERRED;
失去lower(account)
条件:
作为解决方法,您可以执行此丑陋的操作-添加列并触发:
b=# create table "user" (account text, account_uq text);
CREATE TABLE
b=# create function tf() returns trigger as $$ begin NEW.account_uq = lower(NEW.account); return NEW; end;$$ language plpgsql;
ERROR: function "tf" already exists with same argument types
b=# CREATE TRIGGER tg BEFORE UPDATE OR INSERT ON "user" FOR EACH ROW EXECUTE PROCEDURE tf();
CREATE TRIGGER
b=# alter table "user" add CONSTRAINT another_uq UNIQUE(account_uq) deferrable INITIALLY DEFERRED;
ALTER TABLE
b=# insert into "user" (account) select 'b';
INSERT 0 1
b=# begin;
BEGIN
b=# insert into "user" (account) select 'B';
INSERT 0 1
b=# select * from "user";
account | account_uq
---------+------------
b | b
B | b
(2 rows)
b=# end;
ERROR: duplicate key value violates unique constraint "another_uq"
DETAIL: Key (account_uq)=(b) already exists.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.