postgresql - 与 postgresql 中的数组相关的错误“错误:格式错误的记录文字:”
问题描述
我正在尝试将表中的值放入数组中,并且数组定义与表的列定义不同。我试过做演员,但它不工作。基本上我需要表中的值作为数组(tab_small_str)。有人可以建议吗:
CREATE TYPE tab_small_str AS (
str CHARACTER VARYING(50)
);
create table test_emp(emp_id integer, ename character varying (10));
insert into test_emp values(1,'a1')
insert into test_emp values(2,'a2')
insert into test_emp values(3,'a3')
CREATE OR REPLACE function test_fn () RETURNS VARCHAR[] as
$$
DECLARE
v_ename tab_small_str[];
i tab_small_str;
BEGIN
SELECT ARRAY(SELECT ename::tab_small_str FROM test_emp) INTO v_ename;
RAISE INFO 'array is: %',v_ename;
RETURN v_ename;
FOREACH i IN ARRAY v_ename
LOOP
RAISE info 'value of ename is%', i;
END LOOP;
END;
$$
language plpgsql;
(function compiles fine).
select test_fn()
--gives below error
ERROR: malformed record literal: "a1"
DETAIL: Missing left parenthesis.
CONTEXT: SQL statement "SELECT ARRAY(SELECT ename::tab_small_str FROM test_emp)"
PL/pgSQL function test_fn() line 7 at SQL statement
********** Error **********
ERROR: malformed record literal: "a1"
SQL state: 22P02
Detail: Missing left parenthesis.
Context: SQL statement "SELECT ARRAY(SELECT ename::tab_small_str FROM test_emp)"
PL/pgSQL function test_fn() line 7 at SQL statement
嗨 404,我按照建议进行了修改:
CREATE OR REPLACE function test_fn () RETURNS tab_small_str[] as
$$
DECLARE
v_ename tab_small_str[];
i tab_small_str;
BEGIN
SELECT ARRAY(SELECT ROW(ename)::tab_small_str FROM test_emp) INTO v_ename;
RAISE INFO '%',v_ename;
FOREACH i IN ARRAY v_ename
LOOP
RAISE NOTICE '%', i;
END LOOP;
RETURN v_ename;
END;
$$
language plpgsql;
它返回输出为:
INFO: {(a1),(a2),(a3)}
CONTEXT: PL/pgSQL function test_fn() line 9 at RAISE
NOTICE: (a1)
CONTEXT: PL/pgSQL function test_fn() line 13 at RAISE
NOTICE: (a2)
CONTEXT: PL/pgSQL function test_fn() line 13 at RAISE
NOTICE: (a3)
CONTEXT: PL/pgSQL function test_fn() line 13 at RAISE
我的问题是为什么输出被括号包围 - 为什么不只是 a1 而是 (a1)。你能建议一下吗?
解决方案
您的新类型不是“单字段数据类型”,因为需要更好的描述,您可以VARCHAR(10)
直接将其转换为 a ;它是一个包含单个字段的 ROW。所以类似'blah'::tab_small_str
失败的事情是因为它试图将该文本转换为包含字段的类型,而不是字段本身。
要解决,请使用您现有的查询:
SELECT ename::tab_small_str FROM test_emp
改成:
SELECT ROW(ename)::tab_small_str FROM test_emp
至于为什么您的结果被方括号括起来:这就是当显示为单个字段(或非扩展)时如何显示 ROW 或复合类型:例如,如果您这样做SELECT * FROM test_emp
,则将*
所有字段单独作为单独的列返回;但是,如果你这样做SELECT test_emp FROM test_emp
,那将返回未展开的表格行,所以它看起来像这样:
(1,a1)
(2,a2)
(3,a3)
和复合类型完全一样。i tab_small_str;
- 认为i
as test_emp
,其中包含可以扩展的字段。在您的代码中,您正在打印 object i
,而不是i.*
or i.str
。因此,将您的代码更改为:
FOREACH i IN ARRAY v_ename
LOOP
RAISE NOTICE '%', i.str;
END LOOP;
推荐阅读
- android-studio - android studio findViewById 返回 null
- javascript - 在使用 intro.js 的步骤期间触发函数
- for-loop - 捕捉“for循环到达最后一个元素”的优雅方式?
- tensorflow - Keras ValueError: 编译时形状 (?, ?, ?) 和 (6, 1) 必须具有相同的等级 & logits 和标签必须具有相同的形状 ((6, 1) vs (?, ?, ?))
- javascript - 重定向后如何停止浏览器下载javascript文件?
- c - 要求存储字符串,并存储在带有打印的链表中,scanf
- scala - 异步编程缓存不可知(Scala 和其他语言)
- angular - 如何从 Laravel 公开 Angular 的构建?
- javascript - 如何隐藏表单并在单击时显示链接,以及如何在使用 JavaScript 单击表单时隐藏表单并显示链接
- saml - 身份提供者的多个证书(签名和加密)