PostgreSQL中Alter语句可重复执行

1 问题描述

PostgreSQL中通过Alter对表的修改不支持IF NOT EXISTS子句来达成可重复执行的。
例如:

ALTER TABLE "public"."table_name" 
ADD PRIMARY KEY IF NOT EXISTS ("column1", "column2");

上述sql会报如下错误
[Err] ERROR: syntax error at or near “IF”
LINE 2: ADD PRIMARY KEY IF NOT EXISTS (“xxx”, “xxx”);

2 解决方法

DO
$do$
BEGIN
	IF NOT EXISTS(select constraint_name from information_schema.table_constraints where table_name = 'table_name' and constraint_type = 'PRIMARY KEY') 
	THEN 
		ALTER TABLE "public"."table_name" 
		ALTER COLUMN "xxx" SET NOT NULL,
		ALTER COLUMN "xxx" SET NOT NULL, 
		ADD PRIMARY KEY("xxx", "xxx");
	END IF;
END
$do$

也可以写成下方这种:

DO $$
BEGIN
	IF NOT EXISTS(select constraint_name from information_schema.table_constraints where table_name = 'table_name' and constraint_type = 'PRIMARY KEY')
	THEN
		ALTER TABLE "public"."table_name"
		ALTER COLUMN "xxx" SET NOT NULL,
		ALTER COLUMN "xxx" SET NOT NULL,
		ADD PRIMARY KEY("xxx", "xxx");
	END IF;
END $$

还有一种写法,不需要if,then,只需要在添加主键前删除一遍(删除支持if exists)即可。

-- 删除主键
ALTER TABLE "public"."table_name" DROP constraints if exists constraints_name;
ALTER TABLE "public"."table_name" 
ALTER COLUMN "xxx" SET NOT NULL,
ALTER COLUMN "xxx" SET NOT NULL, 
ADD PRIMARY KEY("xxx", "xxx");
### PostgreSQL 常见查询语句示例 #### 1. 查询表的所有列信息 要获取某个表的所有列及其详细信息,可以使用以下查询语句。这有助于理解表的结构和字段定义。 ```sql SELECT column_name, data_type, character_maximum_length, is_nullable, column_default FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'your_table_name'; ``` 此查询会返回指定表的所有列名、数据类型、长度、是否可为空以及默认值等信息[^3]。 --- #### 2. 创建带有自增 ID 的表 创建一张新表时,通常需要设置主键为自动增长(自增)。以下是实现这一功能的标准语法: ```sql CREATE TABLE your_table_name ( id SERIAL PRIMARY KEY, column1 VARCHAR(200), column2 INTEGER ); ``` 如果已有表未设置自增主键,则可通过以下步骤为其添加自增功能: - 添加序列: ```sql CREATE SEQUENCE your_table_id_seq; ``` - 将序列与 `id` 列关联并设置默认值: ```sql ALTER TABLE your_table ALTER COLUMN id SET DEFAULT nextval('your_table_id_seq'); ``` - 重置自增 ID 序列以避免冲突: ```sql SELECT setval('your_table_id_seq', (SELECT MAX(id) FROM your_table) + 1); ``` 以上操作确保了现有记录不会因新增记录而发生主键冲突[^4]。 --- #### 3. 使用 EXPLAIN 分析查询性能 当面对复杂的查询语句时,优化其执行效率至关重要。通过 `EXPLAIN` 或者更详细的 `EXPLAIN ANALYZE` 可以查看查询的实际执行计划,进而定位瓶颈所在。 基本用法如下所示: ```sql EXPLAIN SELECT * FROM your_table WHERE some_column = 'some_value'; ``` 扩展版本加入分析过程: ```sql EXPLAIN ANALYZE SELECT * FROM your_table WHERE some_column = 'some_value'; ``` 这两条命令分别展示了查询规划器的选择依据及具体运行耗时等情况,便于进一步调整索引或重构查询逻辑来提高速度[^1]。 --- #### 4. 联合多张表查询 在处理涉及多个实体间关系的数据检索任务时,经常需要用到连接操作符如 INNER JOIN / LEFT JOIN 。下面给出一个典型例子展示如何正确运用它们完成跨表读取工作。 假设存在两张表——订单 (`orders`) 和客户 (`customers`) ,现在想找出所有客户的姓名连同他们所下过的订单编号列表(即使某些顾客尚未下单也应显示出来)。 错误写法可能导致不符合预期的结果集大小变化等问题;因此务必注意 ON 子句后面附加条件的位置安排合理与否会影响最终输出效果[^2]: ```sql SELECT customers.name AS customer_name, orders.order_id FROM customers LEFT JOIN orders ON customers.id = orders.customer_id AND orders.status = 'active'; ``` 这里强调的是把过滤条件放置于 ON 后面而不是 WHERE 中,这样才能保留左侧全部记录的同时仅筛选符合条件的部分匹配项。 --- #### 5. 查询模式下的所有基表 有时我们需要知道某一特定 schema 下究竟包含了哪些物理存储形式的基础表而非视图之类的虚拟对象。那么可以用到这样的查询表达式: ```sql SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' AND table_type = 'BASE TABLE'; ``` 它列举出了 public 方案里的每一个基础表的名字清单。 --- #### 6. 查询表字段及其类型 另一种更为底层但也更加灵活的方式来取得关于某张特定表内部各个组成部分的信息描述则是直接访问系统 catalog 表族成员之一 —— pg_attribute 结合另一个专门负责管理类型的伙伴 pg_type : ```sql SELECT attr.attname AS name, typ.typname AS type FROM pg_attribute attr JOIN pg_type typ ON attr.atttypid = typ.oid WHERE attr.attrelid = 'public.your_table_name'::regclass AND attr.attnum > 0; ``` 这条语句同样能够揭示出目标表的各项属性细节但是采用了不同的路径达成目的[^4]。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值