[英]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.