首页 > 解决方案 > 如何在另一个“插入”查询中使用“记录”类型的变量字段?

问题描述

我有一个带有复合键的数据库,另一个表引用了该键。简化为网络主机及其端口之间的一个非常简单的示例(省略了此示例中所有不相关的内容),它变成了这样:

       host
---------+--------
scope    | TEXT
hostname | TEXT

       port
---------+--------
scope    | TEXT    <-- Referencing host.scope
hostname | TEXT    <-- Referencing host.hostname
name     | TEXT

我想避免在 SQL 脚本中重复scope和的值。hostname所以我想我可以写和INSERT ... RETURNING ... INTO ...声明,然后在端口的插入中重用返回的记录。所以我想出了以下内容:

BEGIN;
    DO $$
        DECLARE
            result RECORD;
        BEGIN
            CREATE TEMPORARY TABLE host (
                scope TEXT,
                hostname TEXT
            );
            CREATE TEMPORARY TABLE port (
                scope TEXT,
                hostname TEXT,
                name TEXT
            );
            INSERT INTO host (scope, hostname) VALUES ('scope-a', 'hostname')
                RETURNING (scope, hostname) INTO result;
            RAISE NOTICE 'result = %', result;

            INSERT INTO port (scope, hostname, name) VALUES (result.*, 'port-1');
        END
    $$;
ROLLBACK;

我考虑过使用单独的变量,这会起作用,但是当使用像RECORD.

我也尝试使用 a ROWTYPE,但有些表包含NOT NULL约束,这些约束以某种方式阻止我声明具有该类型的变量。

上例中的最后INSERT一条语句失败。result.*语法是我盲目尝试的东西,没有任何运气。因为它是“记录”类型,PostgreSQL 不知道结构,这可能是失败的原因。

有没有办法做到这一点?

标签: postgresqlplpgsql

解决方案


不要使用record,而是两个值的单独变量:

INSERT INTO host ...
   RETURNING scope, hostname INTO v_scope, v_hostname;

INSERT INTO port (scope, hostname, name)
   VALUES (v_scope, v_result, 'port-1');

推荐阅读