我可以使用以下查询添加DEFERRABLE INITIALLY DEFERRED:
ALTER TABLE user DROP CONSTRAINT unq_user_address, add CONSTRAINT unq_user_address UNIQUE(user_address) deferrable INITIALLY DEFERRED;
现在我有另一列,我想添加DEFERRABLE INITIALLY 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表示这是a的延迟重新检查 报告为潜在唯一性违规的行。虽然 这是通过调用aminsert来实现的,访问方法一定不能 在这种情况下插入一个新的索引条目。索引条目已经存在 当下。相反,访问方法必须检查是否存在 另一个实时索引条目。如果是这样,并且目标行也是如此 直播,举报错误。
这是我需要使用的东西,如果是,那么如何?
答案 0 :(得分:1)
您无法将索引定义为可延迟。 Deferrable是约束的属性,而不是索引。
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 "("
因为解析器只处理简单的列引用。
所以你不能让这个检查延期。
答案 1 :(得分:1)
您无法在UNIQUE_CHECK_PARTIAL
SQL查询中同时使用UNIQUE_CHECK_EXISTING
,CREATE INDEX ...
。如您所引用的Access Method Interface 文档页面所述,
... aminsert函数传递一个checkUnique参数 具有以下值之一:UNIQUE_CHECK_NO ..., UNIQUE_CHECK_YES ...,UNIQUE_CHECK_PARTIAL ...,UNIQUE_CHECK_EXISTING
所以那些 checkUnique 参数的值要传递给 aminsert函数(我假设它是Access方法接口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.