postgresql - 如何在另一个“插入”查询中使用“记录”类型的变量字段?
问题描述
我有一个带有复合键的数据库,另一个表引用了该键。简化为网络主机及其端口之间的一个非常简单的示例(省略了此示例中所有不相关的内容),它变成了这样:
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 不知道结构,这可能是失败的原因。
有没有办法做到这一点?
解决方案
不要使用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');
推荐阅读
- node.js - 全局提取已被弃用,并且在未来的版本中将不受支持。npm DropBox 问题
- php - 如何使用 PHP 解析 HTML 表格的单元格和行
- exception - 获取 Dialogflow:API 核心服务不可用错误
- google-chrome - 增加 Chrome 标签页的宽度/立即显示标题
- java - 为什么 Thymeleaf 告诉我:“找不到模板位置:classpath:/templates/”,但实际上有一个文件夹
- azure - Azure 服务总线:如何正确检查订阅是否已存在?
- c - c编程变量读/写限制
- javascript - 为什么不能使用 VueJS 在 vue.config.js 文件中使用 ES 导入?
- mysql - 在mysql中人为地复制结果
- laravel - Laravel 调度程序开始运行但未完成且未显示任何错误