Postgres"不能将非复合值赋给行变量"错误分配复合值

时间:2016-02-01 09:27:04

标签: postgresql plpgsql

我在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,
    ...
)

product和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

以及更新产品的过程,调用update_attribute_value_procedure以更新产品的所有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$

LANGUAGE plpgsql VOLATILE

当我像这样运行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函数change_original_attribute_value()赋值时的第15行 SQL语句" INSERT INTO attribute_value SELECT attr_val。* RETURNING attribute_value.id" PL语句中的PL / pgSQL函数update_attribute_value(attribute_value)第9行 SQL语句" SELECT update_attribute_value(attr_val)" PL / pgSQL函数update_product(product)第17行在PERFORM

在这种情况下,这个错误对我来说完全没有意义。有没有人知道这里有什么问题,或者这可能是个错误?

1 个答案:

答案 0 :(得分:0)

我发现了错误。问题出在函数change_original_attribute_value()内部,该函数在插入产品时触发。在那里调用了一个返回UUID的函数,但它所分配的类型是一个行类型。