PostgreSQL - 如何使用 varchar 参数调用过程

k16*_*yle 6 sql postgresql stored-procedures common-table-expression sql-insert

我正在尝试在 Postgresql 12 中创建 SP:

CREATE OR REPLACE PROCEDURE trans_buy(
        _name_client varchar(25),
        _id_product smallint,
        _mount smallint
    )
    LANGUAGE plpgsql
    AS
    $$

    BEGIN 
        INSERT INTO invoices (cliente) VALUES(_name_client);
        INSERT INTO invoices_details (id_invoice, id_product, mount) VALUES (1, _id_product, _mount, 100);
    END
    $$
Run Code Online (Sandbox Code Playgroud)

但是当我尝试像这样调用这个 sp 时:

CALL trans_buy('james', 3, 10)
Run Code Online (Sandbox Code Playgroud)

我收到此错误消息:

不存在存储过程<< trans_buy(未知,整数,整数)>>

提示:没有过程与参数的名称和类型匹配。可能需要添加显式类型转换。

GMB*_*GMB 7

您可能需要将整数值显式转换为smallints:

call trans_buy('james', 3::smallint, 10::smallint);
Run Code Online (Sandbox Code Playgroud)

我假设中的目标列invoice_details也是smallint如此。另一种方法是让过程接受ints,并在inserttime 进行强制转换:

CREATE OR REPLACE PROCEDURE trans_buy(
    _name_client varchar(25),
    _id_product int,
    _mount int
) LANGUAGE plpgsql
AS $$
BEGIN 
    INSERT INTO invoices (cliente) VALUES(_name_client);
    INSERT INTO invoices_details (id_invoice, id_product, mount) VALUES (1, _id_product::smallint, _mount::smallint);
END
$$
Run Code Online (Sandbox Code Playgroud)

请注意,您的第二个插入有 3 列的 4 个值。我(试图)调整这一点。


还应该强调的是,在 Postgres 中,您实际上并不需要子查询来执行此操作。您可以使用公共表表达式在单个查询中运行多个 DML 操作:

with 
    -- CTE: query parameters
    params(cliente, id_product, mount) as (values ('james', 3, 10)),
    
    -- CTE: insert to invoices
    inv as (insert into invoices (cliente) select cliente from params)

-- insert to invoice details
insert into invoice_details (id_invoice, id_product, mount) 
select 1, id_product, mount from params
Run Code Online (Sandbox Code Playgroud)