日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

修改表字段类型长度_PG修改字段

發(fā)布時間:2024/4/14 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 修改表字段类型长度_PG修改字段 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

今天又遇到一個需求,要把PG中的字段類型修改一下。本來以為是個很簡單的事情,畢竟Oracle就是一條指令就行了。但是在PG中改字段真的真的太難了。

當你修改表字段的時候,會報ERROR: cannot alter type of a column used by a view or rule.

這主要是因為這個表上存在視圖或者是rule,rule這里代表是觸發(fā)器。所以在PG中它不能像Oracle那樣修改字段。一般做法就是:

BEGIN;

DROP VIEW view_name

ALTER TABLE users ALTER COLUMN column_name TYPE character varying(500);

CREATE VIEW view_name AS SELECT * FROM table_name;

COMMIT;

這樣干也沒什么問題,但是一旦上百個視圖依賴于一張表,或者視圖有多個嵌套,這問題就麻煩起來了,特別是有的視圖定義動輒上百上千行的,修改字段再創(chuàng)建視圖,一套弄下來就特別累。那么就沒有什么完美的解決辦法嗎?

通過研究,發(fā)現(xiàn)這個問題有兩種解決辦法,針對兩種不同的情況。

情況一:只修改長度

修改長度,是在日常維護中經常發(fā)生的。比如以前一個字段是20個長度,運行一段時間之后,發(fā)現(xiàn)長度不夠要擴成30。這個時候一般就會通知dba進行操作。我們可以通過修改pg_attribute基表的方式來繞開這個限制。

create table a(id int ,name varchar(20));

create view a_view as select id,name from a;

alter table a alter name type varchar(30);

ERROR: cannot alter type of a column used by a view or rule

DETAIL: rule _RETURN on view a_view depends on column "name"

SELECT atttypmod FROM pg_attribute WHERE attrelid = 'a'::regclass AND attname = 'name';

atttypmod

-----------

24

(1 row)

update pg_attribute set atttypmod =34 WHERE attrelid ='a'::regclass AND attname = 'name';

UPDATE 1

SELECT atttypmod FROM pg_attribute WHERE attrelid = 'a'::regclass AND attname = 'name';

atttypmod

-----------

34

這里需要注意的一點是我設置的是varchar(20),查出來的是varchar(24),這是因為歷史原因,添加了4。我如果要改成30,這里就需要修改為34。

改完之后我們再來查詢我們的表和視圖,發(fā)現(xiàn)都是ok的。

postgres=# \d a

Table "public.a"

Column | ? ? ? ? Type ? ? ? ? ?| Collation | Nullable | Default

--------+-----------------------+-----------+----------+---------

id ? ?| integer ? ? ? ? ? ? ? | ? ? ? ? ? | ? ? ? ? ?|

name ?| character varying(30) | ? ? ? ? ? | ? ? ? ? ?|

postgres=# insert into a values(1,'aaaaaaaaaaaaaaaaaaaaaaaaaaaaa');

INSERT 0 1

postgres=# select lengthb(name) from a;

lengthb

---------

29

postgres=# select * from a_view;

id | ? ? ? ? ? ? name ? ? ? ? ? ? ?

----+-------------------------------

1 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaa

雖然這樣修改能解決問題,但是確實有一定發(fā)生錯誤的風險,所以需要謹慎使用,最好要經過詳細的評審和測試之后再操作。

情況二:修改字段類型

修改字段類型這種情況多見于執(zhí)行SQL緩慢,通過執(zhí)行計劃發(fā)現(xiàn)是字段類型不匹配產生了隱式在轉換,而無法使用上索引。

這種情況就得通過我們之前的方法來實現(xiàn),把刪除視圖、修改字段、創(chuàng)建視圖放到一個事務下執(zhí)行,但是如果嵌套的視圖比較多就很麻煩。為了克服這個麻煩,就有一個大神級人物寫了兩個函數(shù)來輕松實現(xiàn)了這個問題。由于太多人受到這個“煩惱”問題的困擾,作者得到了極高的贊揚。

BEGIN;

select deps_save_and_drop_dependencies('public', 'a');

alter table a alter name type varchar(30);

select deps_restore_dependencies('public', 'a');

COMMIT

以下是我在自己環(huán)境中進行的測試,非常簡單就搞定了。

函數(shù)可以在github上下載:

https://gist.github.com/mateuszwenus/11187288(PG12之前版本)

https://gist.github.com/briandignan/03ef42e78434658cf27f052e2f0798e8(PG12之后的版本)

如果讓我推薦,我還是推薦使用第二種方法,畢竟這個方法比較穩(wěn)妥一點。也基本上達到了比較完美的地步。就算遇到上百個視圖或者像俄羅斯套娃一樣的視圖你也不用擔心了。

參考文檔:

Problemwith Postgres ALTER TABLE

https://stackoverflow.com/questions/3243863/problem-with-postgres-alter-table/49000321

超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

總結

以上是生活随笔為你收集整理的修改表字段类型长度_PG修改字段的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。