使用 pg-promise 执行接受参数数组的 Postgresql 函数

Execute Postgresql function that accepts an array of parameters using pg-promise

我们有这个 postgresql 类型:

create type order_input as (
    item text,
    quantity integer);

而这个 postgresql 函数:

create or replace function insert_into_orders(order_input[])
returns void language plpgsql as $$
declare 
    inserted_id integer;
begin
    insert into public.orders(orderdate) 
    values (now()) 
    returning orderid into inserted_id;

    insert into public.orderdetails(orderid, item, quantity)
    select inserted_id, item, quantity
    from unnest();
end $$;

要在 pgadmin-4 中执行,我们 运行:

select insert_into_orders(
    array[
        ('Red Widget', 10), 
        ('Blue Widget', 5)
    ]::order_input[]
);

我正在尝试找出如何使用 pg-promise javascript 库执行 insert_into_orders 函数。我试过执行以下操作:

const pgp = require("pg-promise")();
const db = pgp(connectionObj);

await db.func("insert_into_orders", [{item:"Red Widget", quantity:10}, {item:"Blue Widget", quantity:5}]

但收到以下消息:

{
  "error": {
    "message": "malformed array literal: \"{\"item\":\"Red Widget\", \"quantity\":10}\""
  }
}

如果有人知道我必须如何构建 pg-promise 的输入,我将不胜感激,原始 post 来自这里:

方法func需要一个值数组作为第二个参数。在您的情况下,它必须是一个参数 - 对象数组。但是你给了它 2 个参数,每个参数都是一个对象,因此会出现错误。

正确的方法是:

const orderInput = [{item:"Red Widget", quantity:10}, {item:"Blue Widget", quantity:5}];

await db.func('insert_into_orders', [orderInput]);

无论如何,你应该使用事件 query or pg-monitor 来查看生成了什么 SQL。

此外,您的 insert_into_orders 至少应该是 stored procedure, and then executed via proc。但是,它的实现看起来应该只是您代码中的一个事务。

After this executed the error came back as "error": {"message": "function insert_into_orders(text[]) does not exist"}

那是因为类型不匹配,需要类型转换...

您可以通过常规查询方法调用该函数,也可以使用Custom Type Formatting修改数据格式:

const data = {
    toPostgres: () => `${pgp.as.array(orderInput)}::json[]::order_input[]`,
    rawType: true
};

然后传入:

await db.func('insert_into_orders', [data]);