代码之家  ›  专栏  ›  技术社区  ›  Eddy Hezarian

postgresql中的函数出现问题

  •  0
  • Eddy Hezarian  · 技术社区  · 2 年前

    在基于Postgresql的SUPABASE函数中,我想写一个函数,将客户的姓名作为输入,然后在函数的主体中实现这样的逻辑,即如果客户尚未创建,则将其插入到客户表中,然后存储其id并创建订单行,如果客户已经存在,则存储其id,然后创建订单

    函数如下:

    create or replace function FUNC_new_order(name text , qty int)
    returns void as 
    $$
    begin
        declare CSID int ; 
        select customer_id into CSID from customer where customer_name = name ; 
        if NOT FOUND then 
        insert into customer(customer_name) values(name);
        select customer_id into CSID from customer where customer_name = name ; 
        --create order 
        insert into "order"(customer_id , order_qty)values(CSID, qty);
    
    end;
    $$
    language plpgsql ; 
    

    但在 苏巴色 它返回这个错误:

    ERROR:  42601: syntax error at or near "into"
    LINE 22:    select customer_id into CSID from customer where customer_name = name ; 
                                   ^
    CONTEXT:  invalid type name "customer_id into CSID from customer where customer_name "
    
    1 回复  |  直到 2 年前
        1
  •  0
  •   Atmo    2 年前

    使用postgres,无论客户是否存在,您都可以在一个查询中插入这两个表。
    示例与 test customer 和数量= 500

    WITH SelectedCustomer AS (
    INSERT INTO Customer(customer_name) VALUES ('test customer') ON CONFLICT DO NOTHING RETURNING customer_id
    )
    INSERT INTO "order"
    SELECT customer_id, 500 FROM SelectedCustomer;
    

    如您所见,该查询使用以下各项的组合:

    • ON CONFLICT DO NOTHING :假设 customer_name unique ,如果新客户端破坏了唯一约束,则不要插入该客户端。
    • RETURNING customer_id :无论是否插入了客户,请给我相应的 customer_id
    • CTE在将记录插入时将所有内容放在一起 order 表(根据你在问题中被迫引用它的方式,我相信你已经知道了,这对一个表来说是一个可怕的名字;我敦促你至少将其重命名为 customer_order 相反)。

    我让您将单个查询放入函数中。如果您愿意,您可以添加 RETURNING order_id 子句来获取创建的订单的id。