如何使用变量的值设置列 DEFAULT

Mar*_*wan 5 postgresql dynamic-sql default-value alter-table plpgsql

在设置使用随机 UUID 作为主键的数据库的脚本中,我有:

CREATE TABLE alpha (id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), value INT);
CREATE TABLE beta (aref UUID REFERENCES alpha (id));

INSERT INTO alpha (value) VALUES (42);
Run Code Online (Sandbox Code Playgroud)

然后通过外键,让“alpha”中的记录成为插入“beta”表的默认目标:

DO $$
    DECLARE l_id UUID;
    BEGIN
        SELECT alpha.id FROM alpha INTO l_id;
        ALTER TABLE beta ALTER COLUMN aref SET DEFAULT l_id;
    END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
ERROR:  column "l_id" does not exist
CONTEXT:  SQL statement "ALTER TABLE beta ALTER COLUMN aref SET DEFAULT l_id"
PL/pgSQL function inline_code_block line 1 at SQL statement
Run Code Online (Sandbox Code Playgroud)

如何使用变量的值作为列的默认值?

Erw*_*ter 5

您似乎假设变量替换为 SQL 实用程序命令,例如ALTER TABLE,但这并未实现。

也不可能将实用程序命令的值传递EXECUTE给 plpgsql 中的子句USING
SO 的相关答案中对两者的详细解释:

连接语句,然后执行它 - 就像@Abelisto 暗示的那样。但你不需要变量,你可以直接连接查找值:

DO $$
BEGIN
EXECUTE format('ALTER TABLE beta ALTER COLUMN aref SET DEFAULT %L'
             , (SELECT a.id::text FROM alpha a));
END $$;
Run Code Online (Sandbox Code Playgroud)

必须SELECT返回单个值。
我明确地转换为text,这并不是绝对必要的。uuid也不需要将字符串文字转换为目标类型。Postgres 会自动从列类型中派生出该值。

有关的: