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

我们有这个 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($1);

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 构建我的输入,我将不胜感激

绝地无双
浏览 90回答 1
1回答

慕码人2483693

方法func需要一个值数组作为第二个参数。在您的情况下,它必须是一个参数 - 对象数组。但是您改为给它 2 个参数,每个参数都是一个对象,因此会出现错误。正确的方法是:const orderInput = [{item:"Red Widget", quantity:10}, {item:"Blue Widget", quantity:5}];await db.func('insert_into_orders', [orderInput]);无论如何,您应该使用事件查询或pg-monitor来查看生成了什么 SQL。另外,您insert_into_orders应该是一个存储过程,然后至少通过proc执行。但是,它的实现看起来应该只是代码中的一个事务。执行此操作后,错误返回为"error": {"message": "function insert_into_orders(text[]) does not exist"}那是因为类型不匹配,这需要类型转换......您可以通过常规查询方法调用该函数,也可以使用自定义类型格式来修改数据格式:const data = {    toPostgres: () => `${pgp.as.array(orderInput)}::json[]::order_input[]`,    rawType: true};然后将其传入:await db.func('insert_into_orders', [data]);
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript