数据库
首页 > 数据库> > postgresql依赖跟踪 cascade和restrict选项

postgresql依赖跟踪 cascade和restrict选项

作者:互联网

weather表的外键为cities的主键city字段,如下为表结构

mydb=# \d weather
                      Table "public.weather"
 Column  |         Type          | Collation | Nullable | Default
---------+-----------------------+-----------+----------+---------
 city    | character varying(80) |           |          |
 temp_lo | integer               |           |          |
 temp_hi | integer               |           |          |
 prcp    | real                  |           |          |
 date    | date                  |           |          |
Foreign-key constraints:
    "weather_city_fkey" FOREIGN KEY (city) REFERENCES cities(city)

mydb=# \d cities
                       Table "public.cities"
  Column  |         Type          | Collation | Nullable | Default
----------+-----------------------+-----------+----------+---------
 city     | character varying(80) |           | not null |
 location | point                 |           |          |
Indexes:
    "cities_pkey" PRIMARY KEY, btree (city)
Referenced by:
    TABLE "weather" CONSTRAINT "weather_city_fkey" FOREIGN KEY (city) REFERENCES cities(city)

删除cities表,报错无法删除,有依赖该表的对象

mydb=# drop table cities ;
2022-06-23 09:38:11.501 CST [7191] ERROR:  cannot drop table cities because other objects depend on it
2022-06-23 09:38:11.501 CST [7191] DETAIL:  constraint weather_city_fkey on table weather depends on table cities
2022-06-23 09:38:11.501 CST [7191] HINT:  Use DROP ... CASCADE to drop the dependent objects too.
2022-06-23 09:38:11.501 CST [7191] STATEMENT:  drop table cities ;
ERROR:  cannot drop table cities because other objects depend on it
DETAIL:  constraint weather_city_fkey on table weather depends on table cities
HINT:  Use DROP ... CASCADE to drop the dependent objects too.
mydb=#
mydb=#

使用cascade选项删除

mydb=# drop table cities CASCADE;
NOTICE:  drop cascades to constraint weather_city_fkey on table weather
DROP TABLE
mydb=# \d
          List of relations
 Schema |   Name   | Type  |  Owner
--------+----------+-------+----------
 public | accounts | table | postgres
 public | product  | table | postgres
 public | rsl      | table | user01
 public | weather  | table | postgres
(4 rows)

mydb=#
mydb=#

cities表已经删除weather表还存在,但是外键约束已经被级联删除

mydb=# \d weather
                      Table "public.weather"
 Column  |         Type          | Collation | Nullable | Default
---------+-----------------------+-----------+----------+---------
 city    | character varying(80) |           |          |
 temp_lo | integer               |           |          |
 temp_hi | integer               |           |          |
 prcp    | real                  |           |          |
 date    | date                  |           |          |

使用restrict选项,其实就是默认的drop table table_name的默认行为,

mydb=# create table city (city varchar(80) primary key,location point);
CREATE TABLE
mydb=# \d city
                        Table "public.city"
  Column  |         Type          | Collation | Nullable | Default
----------+-----------------------+-----------+----------+---------
 city     | character varying(80) |           | not null |
 location | point                 |           |          |
Indexes:
    "city_pkey" PRIMARY KEY, btree (city)

mydb=# alter table city rename to cities;
ALTER TABLE
mydb=#
mydb=# \d cities
                       Table "public.cities"
  Column  |         Type          | Collation | Nullable | Default
----------+-----------------------+-----------+----------+---------
 city     | character varying(80) |           | not null |
 location | point                 |           |          |
Indexes:
    "city_pkey" PRIMARY KEY, btree (city)

mydb=# \d
          List of relations
 Schema |   Name   | Type  |  Owner
--------+----------+-------+----------
 public | accounts | table | postgres
 public | cities   | table | postgres
 public | product  | table | postgres
 public | rsl      | table | user01
 public | weather  | table | postgres
(5 rows)
mydb=# ALTER TABLE weather ADD CONSTRAINT weather_city_fkey FOREIGN KEY (city) REFERENCES cities (city);
ALTER TABLE
mydb=#
mydb=#
mydb=# \d weather
                      Table "public.weather"
 Column  |         Type          | Collation | Nullable | Default
---------+-----------------------+-----------+----------+---------
 city    | character varying(80) |           |          |
 temp_lo | integer               |           |          |
 temp_hi | integer               |           |          |
 prcp    | real                  |           |          |
 date    | date                  |           |          |
Foreign-key constraints:
    "weather_city_fkey" FOREIGN KEY (city) REFERENCES cities(city)

mydb=#
mydb=#
mydb=#
mydb=#
mydb=# drop table cities restrict ;
2022-06-23 09:44:33.279 CST [7191] ERROR:  cannot drop table cities because other objects depend on it
2022-06-23 09:44:33.279 CST [7191] DETAIL:  constraint weather_city_fkey on table weather depends on table cities
2022-06-23 09:44:33.279 CST [7191] HINT:  Use DROP ... CASCADE to drop the dependent objects too.
2022-06-23 09:44:33.279 CST [7191] STATEMENT:  drop table cities restrict ;
ERROR:  cannot drop table cities because other objects depend on it
DETAIL:  constraint weather_city_fkey on table weather depends on table cities
HINT:  Use DROP ... CASCADE to drop the dependent objects too.

对于用户定义的函数,PostgreSQL会追踪与函数外部可见性质相关的依赖性,例如它的参数和结果类型,但不追踪检查函数体才能知道的依赖性。例如,考虑这种情况:

CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow','green', 'blue', 'purple');

CREATE TABLE my_colors (color rainbow, note text);

CREATE FUNCTION get_color_note (rainbow) RETURNS text AS
  'SELECT note FROM my_colors WHERE color = $1'
  LANGUAGE SQL;

PostgreSQL将会注意到get_color_note函数依赖于rainbow类型:删掉该类型会强制删除该函数,因为该函数的参数类型就无法定义了。但是PostgreSQL不会认为get_color_note依赖于my_colors表,因此即使该表被删除也不会删除这个函数。虽然这种方法有缺点,但是也有好处。如果该表丢失,这个函数在某种程度上仍然是有效的,但是执行它会导致错误。创建一个同名的新表将允许该函数重新有效。

实例
创建测试数据

mydb=# CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow','green', 'blue', 'purple');
CREATE TYPE
mydb=# CREATE TABLE my_colors (color rainbow, note text);
CREATE TABLE
mydb=# CREATE FUNCTION get_color_note (rainbow) RETURNS text AS   'SELECT note FROM my_colors WHERE color = $1'   LANGUAGE SQL;
CREATE FUNCTION
mydb=#
mydb=#
mydb=#

查看函数定义

mydb=# \df get_c
get_color_note         get_current_ts_config
mydb=# \df get_color_note
                             List of functions
 Schema |      Name      | Result data type | Argument data types |  Type
--------+----------------+------------------+---------------------+--------
 public | get_color_note | text             | rainbow             | normal
(1 row)

调用函数测试

mydb=# select get_color_note('red');
 get_color_note
----------------

(1 row)

mydb=# select get_color_note('orange');
 get_color_note
----------------

(1 row)

删除表

mydb=# drop table my_colors
mydb-# ;
DROP TABLE

删除表后,该函数还是存在的,重建表之后还是可以调用该函数

mydb=# select get_color_note('orange');
2022-06-23 09:54:27.797 CST [7191] ERROR:  relation "my_colors" does not exist at character 18
2022-06-23 09:54:27.797 CST [7191] QUERY:  SELECT note FROM my_colors WHERE color = $1
2022-06-23 09:54:27.797 CST [7191] CONTEXT:  SQL function "get_color_note" during inlining
2022-06-23 09:54:27.797 CST [7191] STATEMENT:  select get_color_note('orange');
ERROR:  relation "my_colors" does not exist
LINE 1: SELECT note FROM my_colors WHERE color = $1
                         ^
QUERY:  SELECT note FROM my_colors WHERE color = $1
CONTEXT:  SQL function "get_color_note" during inlining
mydb=#
mydb=#
mydb=#
mydb=#  CREATE TABLE my_colors (color rainbow, note text);
CREATE TABLE
mydb=#
mydb=#
mydb=# select get_color_note('orange');
 get_color_note
----------------

(1 row)

删除类型,该类型rainbow是函数的参数,所以将该参数删除后,函数也会被删除

mydb=# drop type rainbow;
2022-06-23 09:54:54.620 CST [7191] ERROR:  cannot drop type rainbow because other objects depend on it
2022-06-23 09:54:54.620 CST [7191] DETAIL:  function get_color_note(rainbow) depends on type rainbow
        table my_colors column color depends on type rainbow
2022-06-23 09:54:54.620 CST [7191] HINT:  Use DROP ... CASCADE to drop the dependent objects too.
2022-06-23 09:54:54.620 CST [7191] STATEMENT:  drop type rainbow;
ERROR:  cannot drop type rainbow because other objects depend on it
DETAIL:  function get_color_note(rainbow) depends on type rainbow
table my_colors column color depends on type rainbow
HINT:  Use DROP ... CASCADE to drop the dependent objects too.
mydb=# drop type rainbow cascade ;
NOTICE:  drop cascades to 2 other objects
DETAIL:  drop cascades to function get_color_note(rainbow)
drop cascades to table my_colors column color
DROP TYPE
mydb=#
mydb=# \df get_clo

mydb=# \df get_clo

mydb=# \df get_clo

mydb=# \df get_color_note;
                       List of functions
 Schema | Name | Result data type | Argument data types | Type
--------+------+------------------+---------------------+------
(0 rows)

mydb=#

参考pg官方文档:http://postgres.cn/docs/14/ddl-depend.html

标签:city,note,postgresql,color,restrict,cascade,table,cities,mydb
来源: https://www.cnblogs.com/nanblog/p/16404112.html