繁体   English   中英

如何访问嵌套的用户定义类型的字段?

[英]How do I access a field of nested user defined types?

嵌套时如何访问用户定义类型的字段? 当我使用点符号尝试它时失败了:

ERROR:  "v_zoo.bear_object.animal_name" is not a known variable
LINE 8:  v_zoo.bear_object.animal_name='Mishka';

例如,我如何“编译”这段代码?

sqls $ cat animal.sql 
DROP TYPE IF EXISTS zoo_t CASCADE;
CREATE TYPE zoo_t AS (
    wolf_object         animal_t,
    bear_object         animal_t

);
DROP TYPE IF EXISTS animal_t CASCADE;
CREATE TYPE animal_t AS (
    animal_id           integer,
    animal_color        varchar,
    animal_name         varchar
);
CREATE OR REPLACE FUNCTION animal_func()
RETURNS void AS $$
DECLARE
    v_animal        animal_t;
    v_zoo           zoo_t;
BEGIN
    v_animal.animal_name:='Chupacabras';
    v_zoo.bear_object.animal_name='Mishka';
END;
$$ LANGUAGE PLPGSQL;

尝试运行它:

sqls $ psql dev < animal.sql 
DROP TYPE
CREATE TYPE
NOTICE:  drop cascades to 2 other objects
DETAIL:  drop cascades to composite type zoo_t column wolf_object
drop cascades to composite type zoo_t column bear_object
DROP TYPE
CREATE TYPE
ERROR:  "v_zoo.bear_object.animal_name" is not a known variable
LINE 8:  v_zoo.bear_object.animal_name='Mishka';
         ^
 sqls $ 

看起来像PL / PgSQL缺陷。 在普通的SQL中,您可以使用

test=> WITH x(zoo) AS (VALUES(ROW( ROW(1, 'red', 'panda')::animal_t, ROW(2, 'black', 'bear')::animal_t )::zoo_t))
SELECT (zoo).bear_object.animal_color FROM x;
 animal_color 
--------------
 black
(1 row)

但是pl / pgsql不接受相同的形式:

test=> CREATE OR REPLACE FUNCTION animal_func()
RETURNS void AS $$
DECLARE
    v_animal        animal_t;
    v_zoo           zoo_t;
BEGIN
    v_animal.animal_name:='Chupacabras';
    (v_zoo).bear_object.animal_name='Mishka';
END;
$$ LANGUAGE PLPGSQL;
ERROR:  syntax error at or near "("
LINE 8:     (v_zoo).bear_object.animal_name='Mishka';

所以我认为这是错误/疏忽/限制。 考虑在pgsql-bugs上提高它。

您可以通过将其解压缩到temp var中,对其进行修改并再次存储来访问它,但这效率低下。

CREATE OR REPLACE FUNCTION animal_func()
RETURNS void AS $$
DECLARE
    v_animal        animal_t;
    v_zoo           zoo_t;
BEGIN
    v_animal := v_zoo.bear_object;
    v_animal.animal_name := 'Mishka';
    v_zoo.bear_object := v_animal;
END;
$$ LANGUAGE PLPGSQL;

就是说:我不建议使用plpgsql来做这种伪OO的事情。 SQL不是OO,因此不能与嵌套的用户定义复合类型配合使用。 修改内容效率很低-SQL中的大多数内容都是不可变的,因此在修改值时会创建新副本。 迭代式更改和过程代码的效果很差。

您应该尝试处理集合和关系。 一遍构造新值,不要迭代地修改它们,并一一设置字段。 使用关系而不是让一个对象包含另一个。

另外, 删除匈牙利符号。 啊。

要访问 postgres 中的复合类型,

SELECT (v_zoo).wolf_object.animal_color FROM TABLE;

当问到这个问题时,postgres 中没有访问复合值类型,但我们现在可以简单地通过 sql 方式来完成。 它从 9.6 开始得到postgres支持。

要了解更多信息,您可以阅读此处

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM