首页 > 解决方案 > 使用 uuid 作为输入参数之一的复合类型数组调用 postgresql 存储过程

问题描述

我有以下用户定义的复合类型

CREATE TYPE item AS (
    SKU_REFERENCE_ID uuid, 
    QUANTITY INTEGER
);

我将它用作 postgresql 存储过程的输入参数的一部分(仅显示存储过程的相关部分)

CREATE OR REPLACE PROCEDURE "dbo"."sp_bulk_update_customer_cart" (IN USER_NAME VARCHAR(20), IN CUSTOMER_ITEMS item[], INOUT QUANTITY INTEGER)

但是,我无法调用该程序。以下是我尝试过的一些事情,但都失败了:

尝试1:

CALL dbo.sp_bulk_update_customer_cart(
    'username',
    (ARRAY['(e3903331-ce0b-4bd5-a853-ec7aa725a812, 20)','(ccbecc39-11bd-4bc4-97d6-7e2f981d30dd, 40)'])::item[], 
    0
);

尝试2:

CALL dbo.sp_bulk_update_customer_cart(
    'username',
    '{"(e3903331-ce0b-4bd5-a853-ec7aa725a812, 20)","(ccbecc39-11bd-4bc4-97d6-7e2f981d30dd, 40)"}'::item[], 
    0
);

尝试 3:

CALL dbo.sp_bulk_update_customer_cart(
    'username',
    (SELECT ARRAY[ROW('e3903331-ce0b-4bd5-a853-ec7aa725a812', 20),ROW('ccbecc39-11bd-4bc4-97d6-7e2f981d30dd', 40)]::item[]), 
    0
);

我得到的最常见的错误是

错误:uuid 类型的输入语法无效:“(e3903331-ce0b-4bd5-a853-ec7aa725a812,20)” 上下文:PL/pgSQL 函数 dbo.sp_bulk_update_customer_cart(字符变化,item[],integer)第 17 行 FOR over SELECT 行SQL状态:22P02

在这里寻求帮助。

使用 AWS RDS postgres 引擎版本:13.3

测试脚本:

DROP PROCEDURE IF EXISTS "dbo"."sp_test_script";

--Not really required as temp tables are deleted after the session ends.
DROP TABLE IF EXISTS item_table;

DROP TYPE IF EXISTS item;

CREATE TYPE item AS (SKU_REFERENCE_ID uuid, QUANTITY integer);

CREATE OR REPLACE PROCEDURE "dbo"."sp_test_script" (IN USER_NAME VARCHAR(20), IN CUSTOMER_ITEMS item[], INOUT QUANTITY INTEGER) 

LANGUAGE PLPGSQL 
    
AS $$

BEGIN

    CREATE TEMP TABLE item_table (
    id SERIAL PRIMARY KEY NOT NULL,
    SKU_REFERENCE_ID uuid, 
    QUANTITY integer
    );
    
    DECLARE b item;

    BEGIN
        FOR b IN SELECT UNNEST(customer_items)
            LOOP
                RAISE NOTICE 'b.sku_reference_id: %', b.sku_reference_id; 
                RAISE NOTICE 'b.quantity: %', b.quantity;
                INSERT INTO item_table(SKU_REFERENCE_ID, QUANTITY) VALUES(b.sku_reference_id, b.quantity);
            END LOOP;
    END;

END; $$;

标签: stored-proceduresplpgsql

解决方案


您在数组迭代中的脚本问题 - FOR b IN SELECT UNNEST(customer_items). 这种语法不做记录的解包,但FOR IN SELECT语句需要它。你需要写:

FOR b IN SELECT * FROM unnest(customer_items)
LOOP
  ...

或更好)

FOREACH b IN ARRAY customer_items
LOOP
  ...

推荐阅读