校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識庫 > PostgreSQL中enable、disable和validate外鍵約束的實例

PostgreSQL中enable、disable和validate外鍵約束的實例

熱門標簽:天津開發區地圖標注app 地圖標注要花多少錢 濟南外呼網絡電話線路 電銷機器人能補救房產中介嗎 移動外呼系統模擬題 電話機器人怎么換人工座席 江蘇400電話辦理官方 400電話申請客服 廣州電銷機器人公司招聘

我就廢話不多說了,大家還是直接看實例吧~

postgres=# create table t1(a int primary key,b text,c date);
CREATE TABLE
postgres=# create table t2(a int primary key,b int references t1(a),c text);
CREATE TABLE
postgres=# insert into t1 (a,b,c) values(1,'aa',now());
INSERT 0 1
postgres=# insert into t1 (a,b,c) values(2,'bb',now());
INSERT 0 1
postgres=# insert into t2 (a,b,c) values (1,1,'aa');
INSERT 0 1
postgres=# insert into t2 (a,b,c) values (2,2,'aa');
INSERT 0 1
postgres=# \d t1
         Table "public.t1"
 Column | Type  | Collation | Nullable | Default
--------+---------+-----------+----------+---------
 a   | integer |      | not null |
 b   | text  |      |     |
 c   | date  |      |     |
Indexes:
  "t1_pkey" PRIMARY KEY, btree (a)
Referenced by:
  TABLE "t2" CONSTRAINT "t2_b_fkey" FOREIGN KEY (b) REFERENCES t1(a)
 
postgres=# \d t2
         Table "public.t2"
 Column | Type  | Collation | Nullable | Default
--------+---------+-----------+----------+---------
 a   | integer |      | not null |
 b   | integer |      |     |
 c   | text  |      |     |
Indexes:
  "t2_pkey" PRIMARY KEY, btree (a)
Foreign-key constraints:
  "t2_b_fkey" FOREIGN KEY (b) REFERENCES t1(a)
 
postgres=#

假設我們想通過腳本向表中加載一些數據。因為我們不知道腳本中加載的順序,我們決定將表t2上的外鍵約束禁用掉,在數據加載之后載開啟外鍵約束:

postgres=# alter table t2 disable trigger all;
ALTER TABLE
postgres=#

這里看起來可能有點奇怪,但是它的確禁用了外鍵約束。如果有其他外鍵約束,當然也是被禁用了。

我們再來看看表t2:

postgres=# \d t2
         Table "public.t2"
 Column | Type  | Collation | Nullable | Default
--------+---------+-----------+----------+---------
 a   | integer |      | not null |
 b   | integer |      |     |
 c   | text  |      |     |
Indexes:
  "t2_pkey" PRIMARY KEY, btree (a)
Foreign-key constraints:
  "t2_b_fkey" FOREIGN KEY (b) REFERENCES t1(a)
Disabled internal triggers:
  "RI_ConstraintTrigger_c_75213" AFTER INSERT ON t2 FROM t1 NOT DEFERRABLE INITIALLY IMMEDIATE FOR EACH ROW EXECUTE PROCEDURE "RI_FKey_check_ins"()
  "RI_ConstraintTrigger_c_75214" AFTER UPDATE ON t2 FROM t1 NOT DEFERRABLE INITIALLY IMMEDIATE FOR EACH ROW EXECUTE PROCEDURE "RI_FKey_check_upd"()
 
postgres=#

關鍵字all將表上的其他內部觸發器也禁用了,需要superser才可以執行成功。

postgres=# create user abce with login password 'abce';
CREATE ROLE
postgres=# \c postgres abce
You are now connected to database "postgres" as user "abce".
postgres=> create table t3 ( a int primary key, b text, c date);
CREATE TABLE
postgres=> create table t4 ( a int primary key, b int references t3(a), c text);
CREATE TABLE
postgres=> alter table t4 disable trigger all;
ERROR: permission denied: "RI_ConstraintTrigger_c_75235" is a system trigger
postgres=>

那作為普通用戶,該如何禁用觸發器呢?

postgres=> alter table t4 disable trigger user;

具體語法為:

DISABLE TRIGGER [ trigger_name | ALL | USER ]

回到t1、t2表。

postgres=# select * from t1;
 a | b |   c   
---+----+------------
 1 | aa | 2020-11-04
 2 | bb | 2020-11-04
(2 rows)
 
postgres=# select * from t2;
 a | b | c 
---+---+----
 1 | 1 | aa
 2 | 2 | aa
(2 rows)
 
postgres=# insert into t2 (a,b,c) values (3,3,'cc');
INSERT 0 1
postgres=#

這里插入了一條在t1中不匹配的記錄,但是插入成功了。

postgres=# alter table t2 enable trigger all;
ALTER TABLE
postgres=# \d t2
         Table "public.t2"
 Column | Type  | Collation | Nullable | Default
--------+---------+-----------+----------+---------
 a   | integer |      | not null |
 b   | integer |      |     |
 c   | text  |      |     |
Indexes:
  "t2_pkey" PRIMARY KEY, btree (a)
Foreign-key constraints:
  "t2_b_fkey" FOREIGN KEY (b) REFERENCES t1(a)
 
postgres=# alter table t2 validate constraint t2_b_fkey;
ALTER TABLE
postgres=#

是不是很驚訝,PostgreSQL沒有報告不匹配的記錄。為什么呢?

查看一個pg_constraint:

postgres=# select * from pg_constraint where conname='t2_b_fkey' and conrelid='t2'::regclass;
-[ RECORD 1 ]-+----------
conname    | t2_b_fkey
connamespace | 2200
contype    | f
condeferrable | f
condeferred  | f
convalidated | t
conrelid   | 75202
contypid   | 0
conindid   | 75200
conparentid  | 0
confrelid   | 75194
confupdtype  | a
confdeltype  | a
confmatchtype | s
conislocal  | t
coninhcount  | 0
connoinherit | t
conkey    | {2}
confkey    | {1}
conpfeqop   | {96}
conppeqop   | {96}
conffeqop   | {96}
conexclop   |
conbin    |
consrc    |
 
postgres=#

convalidated字段的值為t,表明該外鍵約束還是有效的。

哪怕是我們再次將其disable,仍然會顯示是有效的:

postgres=# alter table t2 disable trigger all;
ALTER TABLE
postgres=# select * from pg_constraint where conname='t2_b_fkey' and conrelid='t2'::regclass;
-[ RECORD 1 ]-+----------
conname    | t2_b_fkey
connamespace | 2200
contype    | f
condeferrable | f
condeferred  | f
convalidated | t
conrelid   | 75202
contypid   | 0
conindid   | 75200
conparentid  | 0
confrelid   | 75194
confupdtype  | a
confdeltype  | a
confmatchtype | s
conislocal  | t
coninhcount  | 0
connoinherit | t
conkey    | {2}
confkey    | {1}
conpfeqop   | {96}
conppeqop   | {96}
conffeqop   | {96}
conexclop   |
conbin    |
consrc    |
 
postgres=#

這表明當我們開啟(enable)內部觸發器的時候,PostgreSQL不會驗證(validate)約束,因此也不會驗證數據是否會有沖突,因為外鍵約束的狀態始終是有效的。

我們需要做的是先將其變成無效的:

postgres=# alter table t2 alter CONSTRAINT t2_b_fkey not valid;
ERROR: ALTER CONSTRAINT statement constraints cannot be marked NOT VALID
## 需要先將外鍵刪掉,然后重建外鍵約束并將其狀態設置成無效
 
postgres=# alter table t2 drop constraint t2_b_fkey;
ALTER TABLE
postgres=# delete from t2 where a in (3);
DELETE 1
postgres=# alter table t2 add constraint t2_b_fkey foreign key (b) references t1(a) not valid;
ALTER TABLE
postgres=# \d t2
         Table "public.t2"
 Column | Type  | Collation | Nullable | Default
--------+---------+-----------+----------+---------
 a   | integer |      | not null |
 b   | integer |      |     |
 c   | text  |      |     |
Indexes:
  "t2_pkey" PRIMARY KEY, btree (a)
Foreign-key constraints:
  "t2_b_fkey" FOREIGN KEY (b) REFERENCES t1(a) NOT VALID

現在,可以看到狀態是無效的了:

postgres=# select * from pg_constraint where conname='t2_b_fkey' and conrelid='t2'::regclass;
-[ RECORD 1 ]-+----------
conname    | t2_b_fkey
connamespace | 2200
contype    | f
condeferrable | f
condeferred  | f
convalidated | f
conrelid   | 75202
contypid   | 0
conindid   | 75200
conparentid  | 0
confrelid   | 75194
confupdtype  | a
confdeltype  | a
confmatchtype | s
conislocal  | t
coninhcount  | 0
connoinherit | t
conkey    | {2}
confkey    | {1}
conpfeqop   | {96}
conppeqop   | {96}
conffeqop   | {96}
conexclop   |
conbin    |
consrc    |
 
postgres=#

繼續插入數據:

postgres=# insert into t2(a,b,c) values (3,3,'cc');
ERROR: insert or update on table "t2" violates foreign key constraint "t2_b_fkey"
DETAIL: Key (b)=(3) is not present in table "t1".
postgres=#

是不是更驚訝了?創建了一個無效的約束,只是通知PostgreSQL

不要掃描整個表去驗證所有的行記錄是否有效。對于新插入或更新的行,仍然會檢查是否滿足約束條件,這就是為什么上面插入失敗了。

我們該怎么做呢?

1.刪除所有的外鍵

2.加載數據

3.重新創建外鍵,但是將其狀態設置成無效的,從而避免掃描整個表。之后,新的數據會被驗證了

4.在系統負載低的時候開啟約束驗證(validate the constraints)

另一種方法是:

postgres=# alter table t2 alter constraint t2_b_fkey deferrable;
ALTER TABLE
postgres=# begin;
BEGIN
postgres=# set constraints all deferred;
SET CONSTRAINTS
postgres=# insert into t2 (a,b,c) values (3,3,'cc');
INSERT 0 1
postgres=# insert into t2 (a,b,c) values (4,4,'dd');
INSERT 0 1
postgres=# insert into t1 (a,b,c) values (3,'cc',now());
INSERT 0 1
postgres=# insert into t1 (a,b,c) values (4,'dd',now());
INSERT 0 1
postgres=# commit;
COMMIT

這樣做不好的方面是,在下一次提交時才起作用,因此,你需要將所有的工作放到一個事務中。

本文的關鍵點是,下面的假設將驗證你的數據是錯誤的:

postgres=# alter table t2 disable trigger all;
ALTER TABLE
postgres=# insert into t2 (a,b,c) values (5,5,'ee');
INSERT 0 1
postgres=# alter table t2 enable trigger all;
ALTER TABLE
postgres=#

這只會驗證新的數據,但是并不保證所有的數據都滿足約束:

postgres = # insert into t2 (a,b,c) values (6,6,'ff');
ERROR: insert or update on table "t2" violates foreign key constraint "t2_b_fkey"
DETAIL: Key(b) = (6) is not present in table "t1".
postgres = # select * from t2 where b = 5;
a | b | c
---+---+----
5 | 5 | ee
(1 row)
 
postgres = # select * from t1 where a = 5;
a | b | c
---+---+---
(0 rows)

最終,還有一種方式來解決,直接修改pg_constraint目錄表。但是并建議用戶這么做!

postgres=# delete from t2 where b = 5;
DELETE 1
postgres=# delete from t2 where b = 5;
DELETE 1
postgres=# alter table t2 disable trigger all;
ALTER TABLE
postgres=# insert into t2 values (5,5,'ee');
INSERT 0 1
postgres=# alter table t2 enable trigger all;
ALTER TABLE
postgres=# update pg_constraint set convalidated = false where conname = 't2_b_fkey' and conrelid = 't2'::regclass;
UPDATE 1
postgres=# alter table t2 validate constraint t2_b_fkey;
ERROR: insert or update on table "t2" violates foreign key constraint "t2_b_fkey"
DETAIL: Key (b)=(5) is not present in table "t1".
postgres=#

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

您可能感興趣的文章:
  • PostgreSQL 查看表的主外鍵等約束關系詳解
  • postgresql 實現字符串分割字段轉列表查詢
  • postgresql 查詢集合結果用逗號分隔返回字符串處理的操作
  • postgresql數據庫連接數和狀態查詢操作
  • postgresql查詢自動將大寫的名稱轉換為小寫的案例
  • postgresql數據庫使用說明_實現時間范圍查詢
  • Postgresql 查詢表引用或被引用的外鍵操作

標簽:辛集 杭州 寶雞 溫州 濮陽 榆林 海西 昭通

巨人網絡通訊聲明:本文標題《PostgreSQL中enable、disable和validate外鍵約束的實例》,本文關鍵詞  PostgreSQL,中,enable,disable,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《PostgreSQL中enable、disable和validate外鍵約束的實例》相關的同類信息!
  • 本頁收集關于PostgreSQL中enable、disable和validate外鍵約束的實例的相關信息資訊供網民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    99精品久久99久久久久| 成人免费毛片片v| 粉嫩av一区二区三区在线播放| 精品88久久久久88久久久| 国产一区二区久久| 亚洲图片另类小说| 337p亚洲精品色噜噜| 国产在线不卡一区| 亚洲免费观看高清完整版在线观看| 欧美在线小视频| 精品写真视频在线观看 | 成人精品国产一区二区4080| 国产精品美女久久久久aⅴ国产馆 国产精品美女久久久久av爽李琼 国产精品美女久久久久高潮 | 国产精品久久久久久久久果冻传媒 | 亚洲乱码精品一二三四区日韩在线| 欧美日韩亚洲综合在线| 国产精品一级二级三级| 亚洲黄色免费电影| 久久久精品国产免费观看同学| 91福利在线免费观看| 国产成人免费高清| 另类调教123区| 亚洲精品乱码久久久久| 日本一区二区三区四区| 欧美一级高清片| 在线观看91精品国产入口| 国产成人av一区二区三区在线 | 在线这里只有精品| 亚洲国产精品欧美一二99| 日韩午夜av电影| 日本韩国一区二区| 99在线精品观看| 国产综合久久久久影院| 亚洲综合在线电影| 中文字幕精品一区二区三区精品| 91精选在线观看| 欧美日产国产精品| 在线一区二区视频| 91偷拍与自偷拍精品| 懂色av一区二区夜夜嗨| 国模无码大尺度一区二区三区| 五月天丁香久久| 午夜欧美在线一二页| 亚洲亚洲精品在线观看| 一区二区免费在线播放| 亚洲精选在线视频| 亚洲欧美激情小说另类| 亚洲人成影院在线观看| 日韩美女啊v在线免费观看| 国产免费成人在线视频| 国产日产精品一区| 国产三级久久久| 久久九九99视频| 欧美精品一区二区蜜臀亚洲| 欧美电影免费观看高清完整版在线 | 欧美一区二区高清| 欧美一区二区三区精品| 日韩一区二区免费视频| 精品国内片67194| 国产亚洲一区二区三区在线观看 | 欧美视频在线一区| 欧美高清dvd| 日韩欧美卡一卡二| 国产色综合久久| 国产精品毛片无遮挡高清| 国产精品久久久99| 亚洲最大成人网4388xx| 日本网站在线观看一区二区三区| 日本va欧美va欧美va精品| 精品一区二区三区免费毛片爱| 国产精品综合一区二区三区| 国产福利电影一区二区三区| av综合在线播放| 欧美日韩极品在线观看一区| 亚洲精品在线一区二区| 综合久久给合久久狠狠狠97色| 亚洲欧美国产毛片在线| 国产欧美日韩三级| 一区二区三区中文免费| 日本vs亚洲vs韩国一区三区二区 | 精品理论电影在线观看| 国产日韩欧美综合在线| 一区二区在线观看不卡| 美女国产一区二区三区| 成人免费视频网站在线观看| 在线这里只有精品| 337p粉嫩大胆色噜噜噜噜亚洲| 日韩一区欧美小说| 狂野欧美性猛交blacked| a4yy欧美一区二区三区| 91精品国产色综合久久久蜜香臀| 久久精品欧美日韩| 日韩成人免费看| 91首页免费视频| 精品欧美一区二区在线观看| 亚洲视频每日更新| 国产一区二区三区最好精华液| 91亚洲国产成人精品一区二三| 在线视频一区二区三| 久久久777精品电影网影网 | 国产精品白丝jk黑袜喷水| 欧美性高清videossexo| 国产精品入口麻豆九色| 蜜臀av在线播放一区二区三区| 97精品久久久午夜一区二区三区| 精品卡一卡二卡三卡四在线| 亚洲一卡二卡三卡四卡无卡久久| 国产成人精品免费视频网站| 日韩一区二区在线观看视频 | 国产精品一区2区| 日韩欧美一级片| 五月激情六月综合| 91久久国产最好的精华液| 国产精品久久久久久久第一福利 | 蜜臀99久久精品久久久久久软件| 色呦呦一区二区三区| 国产亚洲人成网站| 国产麻豆视频精品| 欧美r级在线观看| 日本欧美在线观看| 欧美日韩视频在线第一区 | 蜜桃av噜噜一区| 欧美精品亚洲二区| 亚洲成av人**亚洲成av**| 色香色香欲天天天影视综合网| 中文幕一区二区三区久久蜜桃| 韩国精品久久久| 久久久亚洲午夜电影| 国产精品一区二区无线| 日韩精品一区二区三区四区视频| 日韩激情视频网站| 日韩亚洲欧美在线| 精品亚洲免费视频| 久久无码av三级| 国产成人小视频| 国产精品午夜春色av| 色综合一个色综合亚洲| 亚洲一区二区av在线| 欧美福利视频导航| 麻豆精品新av中文字幕| 国产午夜三级一区二区三| 国产成人av一区二区三区在线| 欧美经典三级视频一区二区三区| 成人伦理片在线| 亚洲黄色片在线观看| 欧美日韩精品欧美日韩精品一 | 极品销魂美女一区二区三区| 国产拍揄自揄精品视频麻豆| 91在线小视频| 天天色天天爱天天射综合| 精品88久久久久88久久久| 91影院在线免费观看| 奇米影视7777精品一区二区| 久久精品夜色噜噜亚洲aⅴ| 成人av网站在线观看| 亚洲成人av一区二区| 2023国产精品| 欧美天堂亚洲电影院在线播放| 毛片av一区二区三区| 亚洲欧美激情小说另类| 日韩精品资源二区在线| 99久久精品国产一区| 免费xxxx性欧美18vr| 国产真实乱偷精品视频免| 色综合久久六月婷婷中文字幕| 亚洲欧美区自拍先锋| 亚洲无线码一区二区三区| 日韩三级中文字幕| av电影一区二区| 蜜桃久久av一区| 亚洲久草在线视频| 欧美成人性战久久| 色婷婷av一区二区三区大白胸| 日本系列欧美系列| 一区二区三区免费在线观看| 精品国产伦一区二区三区免费| 色综合中文字幕国产 | 国产清纯在线一区二区www| 91久久一区二区| 国产一区二区三区在线观看免费视频 | 日韩av一区二区三区四区| 欧美激情一区二区三区不卡| 欧美肥妇free| 色综合久久久网| 成人av电影观看| 国产在线麻豆精品观看| 亚洲欧洲成人自拍| 2023国产精品自拍| 欧美成人精品二区三区99精品| 91天堂素人约啪| 成人精品视频一区| 久久国产精品99久久久久久老狼| 亚洲精选在线视频| 亚洲视频在线观看一区| 国产网站一区二区三区| 欧美系列在线观看| 日本黄色一区二区| 91捆绑美女网站| 91猫先生在线| 一本久道久久综合中文字幕|