大多数PostgreSQL语句支持IF NOT EXISTS子句以允许幂等迁移,例如CREATE TABLE IF NOT EXISTS foo ...。但ALTER TABLE ... ADD CONSTRAINT不存在。如果约束不存在,我如何编写一条添加约束的SQL语句,否则什么都不做,不出错?
CREATE TABLE IF NOT EXISTS foo ...
ALTER TABLE ... ADD CONSTRAINT
8i9zcol21#
这是PostgreSQL语法中的一种令人讨厌的差距。以下是一些解决方法:
用于唯一约束
CREATE UNIQUE INDEX IF NOT EXISTS indexname ON tablename(columns)
这等效于添加唯一约束,因为唯一约束是通过添加索引实现的。
使用PLSQL
来自here:
CREATE OR REPLACE FUNCTION create_constraint_if_not_exists (t_name text, c_name text, constraint_sql text) RETURNS void AS $BODY$ BEGIN -- Look for our constraint IF NOT EXISTS (SELECT constraint_name FROM information_schema.constraint_column_usage WHERE constraint_name = c_name) THEN EXECUTE 'ALTER TABLE ' || t_name || ' ADD CONSTRAINT ' || c_name || ' ' || constraint_sql; END IF; END; $BODY$ LANGUAGE plpgsql VOLATILE; SELECT create_constraint_if_not_exists('pokemon', 'league_max', 'CHECK (cp < 1500);');
这在波斯格雷斯很管用。CockroachDB目前还不支持pl/pgSQL(截至2022年10月),但很快就会支持。
在代码中
if sqlconn.Query("SELECT 1 FROM information_schema.constraint_column_usage WHERE constraint_name = league_max").empty? sqlConn.Exec("ALTER TABLE pokemon ADD CONSTRAINT league_max ...")
如果表当前未接收写入
ALTER TABLE pokemon DROP CONSTRAINT IF EXISTS league_max; ALTER TABLE pokemon ADD CONSTRAINT league_max ...
这是一种简单的方法,适用于CockroachDB和Postgres上的任何类型的约束,但在生产中对活动表使用是不安全的,如果表很大,可能会很昂贵。
1条答案
按热度按时间8i9zcol21#
这是PostgreSQL语法中的一种令人讨厌的差距。以下是一些解决方法:
用于唯一约束
这等效于添加唯一约束,因为唯一约束是通过添加索引实现的。
使用PLSQL
来自here:
这在波斯格雷斯很管用。CockroachDB目前还不支持pl/pgSQL(截至2022年10月),但很快就会支持。
在代码中
如果表当前未接收写入
这是一种简单的方法,适用于CockroachDB和Postgres上的任何类型的约束,但在生产中对活动表使用是不安全的,如果表很大,可能会很昂贵。