Postgres "cannot assign non-composite value to a row variable" 分配复合值时出错
Postgres "cannot assign non-composite value to a row variable" error assigning a composite value
我在 Postgresql 9.4 上更新产品及其属性的两个过程遇到以下问题。首先离开表格:
CREATE TABLE product
(
id uuid NOT NULL,
version bigint NOT NULL,
is_part_of_import_id uuid,
name text NOT NULL,
owner_id uuid NOT NULL,
replaced_by_id uuid,
state character varying(255) NOT NULL,
replaces_id uuid,
last_update timestamp without time zone,
...
)
CREATE TABLE attribute_value
(
id uuid NOT NULL,
version bigint NOT NULL,
last_update timestamp without time zone,
product_id uuid NOT NULL,
replaced_by_id uuid,
replaces_id uuid,
value text,
...
)
产品与attribute_value之间存在一对多关系。我有一个更新 attribute_value
的程序
CREATE OR REPLACE FUNCTION update_attribute_value(attr_val attribute_value)
RETURNS UUID AS
$BODY$
DECLARE new_id UUID;
BEGIN
attr_val.replaces_id := attr_val.id;
attr_val.id := uuid_generate_v4();
attr_val.last_update := NOW();
INSERT INTO attribute_value SELECT attr_val.* RETURNING attribute_value.id INTO new_id;
UPDATE attribute_value SET replaced_by_id = new_id WHERE id = attr_val.replaces_id;
RETURN attr_val.id;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
和更新产品的过程调用更新_attribute_value_过程来更新产品的所有 attribute_values
CREATE OR REPLACE FUNCTION update_product(prod product)
RETURNS UUID AS
$BODY$
DECLARE new_id UUID;
DECLARE attr_val attribute_value%ROWTYPE;
BEGIN
prod.replaces_id := prod.id;
prod.id := uuid_generate_v4();
prod.last_update := NOW();
INSERT INTO product SELECT prod.* RETURNING id INTO new_id;
UPDATE product SET replaced_by_id = new_id WHERE id = prod.replaces_id;
FOR attr_val IN
SELECT * FROM attribute_value WHERE product_id = prod.replaces_id
LOOP
attr_val.product_id = new_id;
PERFORM update_attribute_value(attr_val);
END LOOP;
RETURN new_id;
END;
$BODY$
语言 plpgsql 易失性
当我运行update_product这样
select update_product(row('140613c5-3e83-4ae2-986e-5c6b824d5766', 0, '0ba5a6c8-2513-4163-a5bd-c460e10d2059', null, null,
'ce594f2c-87f9-497a-a0e5-7d3fbc4abd8a', null, 'aeabe6fe-b9e1-47e5-96a7-7bf16c56ddf4', 'Rotak 43 1', 'eaf6bea0-99c4-4759-8c38-d35b9ae11403', null,
'PENDING', null, null)::product);
我得到以下错误输出:
错误:无法将非复合值分配给行变量
SQL 状态:42804
上下文:PL/pgSQL function change_original_attribute_value() line 15 at assignment
SQL 声明 "INSERT INTO attribute_value SELECT attr_val.* RETURNING attribute_value.id"
PL/pgSQL 函数 update_attribute_value(attribute_value) 第 9 行在 SQL 语句
SQL 声明 "SELECT update_attribute_value(attr_val)"
PL/pgSQL 函数 update_product(产品)第 17 行在 PERFORM
在这种情况下,这个错误对我来说毫无意义。有谁知道这里出了什么问题,或者这可能是一个错误?
我发现了错误。问题出在插入产品时触发的函数 change_original_attribute_value() 内。在那里调用了一个函数,returns 一个 UUID,但分配给它的类型是一个行类型。
我在 Postgresql 9.4 上更新产品及其属性的两个过程遇到以下问题。首先离开表格:
CREATE TABLE product
(
id uuid NOT NULL,
version bigint NOT NULL,
is_part_of_import_id uuid,
name text NOT NULL,
owner_id uuid NOT NULL,
replaced_by_id uuid,
state character varying(255) NOT NULL,
replaces_id uuid,
last_update timestamp without time zone,
...
)
CREATE TABLE attribute_value
(
id uuid NOT NULL,
version bigint NOT NULL,
last_update timestamp without time zone,
product_id uuid NOT NULL,
replaced_by_id uuid,
replaces_id uuid,
value text,
...
)
产品与attribute_value之间存在一对多关系。我有一个更新 attribute_value
的程序CREATE OR REPLACE FUNCTION update_attribute_value(attr_val attribute_value)
RETURNS UUID AS
$BODY$
DECLARE new_id UUID;
BEGIN
attr_val.replaces_id := attr_val.id;
attr_val.id := uuid_generate_v4();
attr_val.last_update := NOW();
INSERT INTO attribute_value SELECT attr_val.* RETURNING attribute_value.id INTO new_id;
UPDATE attribute_value SET replaced_by_id = new_id WHERE id = attr_val.replaces_id;
RETURN attr_val.id;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
和更新产品的过程调用更新_attribute_value_过程来更新产品的所有 attribute_values
CREATE OR REPLACE FUNCTION update_product(prod product)
RETURNS UUID AS
$BODY$
DECLARE new_id UUID;
DECLARE attr_val attribute_value%ROWTYPE;
BEGIN
prod.replaces_id := prod.id;
prod.id := uuid_generate_v4();
prod.last_update := NOW();
INSERT INTO product SELECT prod.* RETURNING id INTO new_id;
UPDATE product SET replaced_by_id = new_id WHERE id = prod.replaces_id;
FOR attr_val IN
SELECT * FROM attribute_value WHERE product_id = prod.replaces_id
LOOP
attr_val.product_id = new_id;
PERFORM update_attribute_value(attr_val);
END LOOP;
RETURN new_id;
END;
$BODY$
语言 plpgsql 易失性
当我运行update_product这样
select update_product(row('140613c5-3e83-4ae2-986e-5c6b824d5766', 0, '0ba5a6c8-2513-4163-a5bd-c460e10d2059', null, null,
'ce594f2c-87f9-497a-a0e5-7d3fbc4abd8a', null, 'aeabe6fe-b9e1-47e5-96a7-7bf16c56ddf4', 'Rotak 43 1', 'eaf6bea0-99c4-4759-8c38-d35b9ae11403', null,
'PENDING', null, null)::product);
我得到以下错误输出:
错误:无法将非复合值分配给行变量 SQL 状态:42804 上下文:PL/pgSQL function change_original_attribute_value() line 15 at assignment SQL 声明 "INSERT INTO attribute_value SELECT attr_val.* RETURNING attribute_value.id" PL/pgSQL 函数 update_attribute_value(attribute_value) 第 9 行在 SQL 语句 SQL 声明 "SELECT update_attribute_value(attr_val)" PL/pgSQL 函数 update_product(产品)第 17 行在 PERFORM
在这种情况下,这个错误对我来说毫无意义。有谁知道这里出了什么问题,或者这可能是一个错误?
我发现了错误。问题出在插入产品时触发的函数 change_original_attribute_value() 内。在那里调用了一个函数,returns 一个 UUID,但分配给它的类型是一个行类型。