[英]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.