当前位置:网站首页>PostgreSQL: cannot change the type of column used by a view or rule
PostgreSQL: cannot change the type of column used by a view or rule
2022-07-28 08:41:00 【Ouchen Eli】
At one time about PostgreSQL Lectures , A participant raised a puzzling question : How to integrate ALTER COLUMN Cascade a table to a view ? There are two main methods : Use DDL You can trade the power of commands or change the system directory . In this article , I explained how to do these two points .
Imagine , You have a table and a view built on it ( Dynamic or materialized ):
> CREATE TABLE t( pk smallint, t char(2) );
> CREATE VIEW vw_t AS SELECT * FROM t;Of course , Both views and tables reflect the same field structure
> \d t
Table "public.t"
Column | Type | Collation | Nullable | Default
--------|--------------|-----------|----------|---------
pk | smallint | | |
t | character(2) | | |
> \d vw_t
View "public.vw_t"
Column | Type | Collation | Nullable | Default
--------|--------------|-----------|----------|---------
pk | smallint | | |
t | character(2) | | | If t What happens when a table changes its structure ?PostgreSQL This is not allowed , Because existence comes from vw_tover Dependence t:
> ALTER TABLE t ALTER COLUMN t TYPE char(10);
ERROR: cannot alter type of a column used by a view or rule
DETAIL: rule _RETURN on view vw_t depends on column "t"
> ALTER TABLE t ALTER COLUMN pk TYPE bigint;
ERROR: cannot alter type of a column used by a view or rule
DETAIL: rule _RETURN on view vw_t depends on column "pk" The DETAIL The message provides tips about the problem :"_RETURN" The rule is PostgreSQL Special way to deal with views : It will indeed `SELECT** The statement bounces back to the base table . There is only one correct way to solve this problem : because PostgreSQL It is allowed to include any DDL command , So you can use transactions to delete views 、 Change the table and recreate the view :
> BEGIN;
> DROP VIEW vw_t;
> ALTER TABLE t ALTER COLUMN pk TYPE bigint;
> ALTER TABLE t ALTER COLUMN t TYPE char(10);
> CREATE VIEW vw_t AS SELECT * FROM t;
> COMMIT; Because there is no need to compile views as in other database systems , Therefore, you should never fail to perform the above operations on the real-time system . In rare cases where the above transaction cannot be started , You can change the system directory to reflect the desired structure . Check pg_attribute The system catalog shows how tables are defined :
> SELECT attname, atttypmod, attlen
FROM pg_attribute
WHERE attname IN ( 'pk', 't' )
AND attrelid = 't'::regclass;
attname | atttypmod | attlen
---------|-----------|--------
pk | -1 | 2
t | 6 | -1 In short ,pk Columns that are numbers have no type modifiers ( atttypmod) And the total length ( attlen)2 byte ( It is a smallint); On the other hand , The t The column has no specific length , But there is a modifier 6, especially 4 Added by the length itself ( under these circumstances , yes a char(2))2 + 4 = 6.
Suppose you have to change the table to make pka Turn into bigint Column ta char(10): You can force it on the directory itself . While you can t Modify the column directly on the directory to increase the length of the type modifier , But that is pk It's impossible on the list , because pg_attribute.attlen It's not true , It is pg_type.typlen Copy as shown in the figure stay pg_attribute file in . therefore ,t The table must be updated as follows : 1) Change the type of numeric column pk;2) Change the type modifier length of the column t, take PostgreSQL Required for reservation 4 Bytes are added to the desired value .
The above two steps must be performed as super user , therefore If you can't get super user permission , The table structure cannot be updated through the system directory . The other thing to note is that , The name inside pg_type No SQL name , It is PostgreSQL Internal name ; let me put it another way , The bigint The type is named int8.
Let's look at the actual process :
# BEGIN;
# UPDATE pg_attribute
SET atttypid =
( SELECT oid
FROM pg_type
WHERE typname = 'int8' )
WHERE attname = 'pk'
AND attrelid = 't'::regclass;
# UPDATE pg_attribute SET atttypmod = 14
WHERE attname = 't'
AND attrelid = 't'::regclass;
# \d t
Table "public.t"
Column | Type | Collation | Nullable | Default
--------|---------------|-----------|----------|---------
pk | bigint | | |
t | character(10) | | |
# \d vw_t
View "public.vw_t"
Column | Type | Collation | Nullable | Default
--------|--------------|-----------|----------|---------
pk | smallint | | |
t | character(2) | | |
-- if ready commit changes ... Of course , This is not necessary , So I strongly oppose submitting the above matters . You need to target the entire dependent object ( under these circumstances vw_t) Replay the same statement . If the view keeps its old structure , Strange behavior may occur , Because the extracted value can be read regularly ( namely ,t Columns will be restricted by the underlying table , therefore a char(10)) But the update of the view may cause data truncation .
Again , stay PostgreSQL The correct way to perform this structural change in is to use normal transactions , Once the table changes , Delete dependent objects and recreate them in the same transaction .
Be careful when using system directories , And ensure that the data is effectively backed up before changing it , Because this is not to let PostgreSQL The expected way to protect data !
边栏推荐
- Shell编程规范与变量
- CAT1 4g+ Ethernet development board 232 data is sent to the server through 4G module TCP
- 一篇文章搞懂数据仓库:元数据分类、元数据管理
- [Qt5] a method of multi window parameter transmission (using custom signal slot) and case code download
- [Qt5] small software with 5 people randomly selected from the bid evaluation expert base
- How to configure phpunit under window
- Recycling of classes loaded by classloader
- 快速搭建一个网关服务,动态路由、鉴权的流程,看完秒会(含流程图)
- tkMapper的使用-超详细
- 客户至上 | 国产BI领跑者,思迈特软件完成C轮融资
猜你喜欢

业务数字化飞速奔跑,管理数字化亟待出发

uniapp---- 获取当前位置的经纬度等信息的详细步骤(包含小程序)

leetcode刷题,我推荐B站这个妹子学霸的视频

One key switch circuit

Can‘t connect to server on ‘IP‘ (60)

GBase 8a MPP与银河麒麟(x86版)完成深度适配
![[Qt5] a method of multi window parameter transmission (using custom signal slot) and case code download](/img/6d/870add6179f0e3a2f9b719f79594f3.png)
[Qt5] a method of multi window parameter transmission (using custom signal slot) and case code download

2022牛客多校第二场解题报告

Day112.尚医通:手机验证码登录功能

Half bridge buck circuit - record
随机推荐
How to write a JMeter script common to the test team
快速搭建一个网关服务,动态路由、鉴权的流程,看完秒会(含流程图)
Use of tkmapper - super detailed
File editing component
MySQL how to add users and set permissions?
[soft test software evaluator] 2013 comprehensive knowledge over the years
The cooperation between starfish OS and metabell is just the beginning
二维数组及操作
Understand the propagation process of EMI electromagnetic interference through five diagrams - the influence of square wave steepness on high-frequency components, the spectrum graph from time sequenc
GBase 8a MPP与银河麒麟(x86版)完成深度适配
HCIP---LDP和MPLS技术(详解)
Gbase appears in Unicom cloud Tour (Sichuan Station) to professionally empower cloud ecology
leetcode/单词长度的最大乘积
feign 调用
Uniapp ---- detailed steps to obtain the longitude and latitude of the current position and other information (including applet)
Js继承方法
第2章-14 求整数段和
Vk1620 temperature controller / smart meter LED digital display driver chip 3/4-wire interface with built-in RC oscillator to provide technical support
Usage of qcombobox
QT 怎么删除布局里的所有控件?