Postgresql:有没有办法从Microsoft SQL Server中的存储过程返回表数据和输出参数

时间:2017-12-13 10:37:24

标签: sql postgresql stored-procedures plpgsql

在Microsoft Sql Server中,输出参数和选择结果都可用于内聚,以将数据返回给客户端。这在分页等用例中非常方便,您需要返回一个主集以及相关的元数据,如总页数。到目前为止,我在Postgres中看到的所有示例都是通过输出参数或表结果返回数据。我无法一起创建一个过程,因为它失败并出现以下错误: 错误:TABLE函数中不允许使用OUT和INOUT参数

以下是我的尝试:

CREATE OR REPLACE FUNCTION fn_Test(out p_count int)
RETURNS TABLE (CustomerId int, CustomerName varchar(50))
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN

    INSERT INTO Customers(CustomerName, Address, Area, Phonenumber, Email, communicationpreference)
    VALUES ('Julie Yellow', 'JY Ad', 'JY Ar', 'JV0987654', 'j@ye.com', 1);

    SELECT COUNT(*) FROM CUSTOMERS INTO  p_count;
    SELECT CustomerId, CustomerName FROM Customers;
EXCEPTION WHEN OTHERS THEN
    RAISE exception '% %', SQLERRM, SQLSTATE;
END;
$BODY$

他们不能一起去吗?在Postgresql中有没有替代方法?

请咨询

3 个答案:

答案 0 :(得分:1)

答案是否定的 - 要么创建函数返回某些内容,要么由OUT参数定义某些内容。

https://www.postgresql.org/docs/current/static/plpgsql-control-structures.html

  

如果您使用输出参数声明了该函数,请只写RETURN   没有表达。 输出参数的当前值   变量将被退回

ephasis mine。

https://www.postgresql.org/docs/current/static/sql-createfunction.html

  

OUT和INOUT参数也不能与RETURNS一起使用   表符号

您可以使用raise infonotify频道播放

答案 1 :(得分:1)

您只需在最终查询中包含计数即可。

但要从PL / pgSQL返回查询结果,您需要使用return query

CREATE OR REPLACE FUNCTION fn_test()
   RETURNS TABLE (customerid int, customername varchar(50), newcount int)
AS $BODY$
BEGIN

    INSERT INTO customers(customername, address, area, phonenumber, email, communicationpreference)
    VALUES ('Julie Yellow', 'JY Ad', 'JY Ar', 'JV0987654', 'j@ye.com', 1);

    return query
      SELECT customerid, customername, count(*) over () as newcount
      FROM customers;
EXCEPTION WHEN OTHERS THEN
    RAISE exception '% %', SQLERRM, SQLSTATE;
END;
$BODY$
LANGUAGE plpgsql;

语言名称是标识符,不要将其放入单引号中。

或者,您可以从函数中返回多个结果作为refcursors。但是对于大多数SQL客户端来说,这有点笨拙:

CREATE OR REPLACE FUNCTION fn_test()
   returns setof refcursor
AS $BODY$
DECLARE
   c1 refcursor;
   c2 refcursor;
BEGIN

    INSERT INTO customers(customername, address, area, phonenumber, email, communicationpreference)
    VALUES ('Julie Yellow', 'JY Ad', 'JY Ar', 'JV0987654', 'j@ye.com', 1);

    open c1 for 
      select count(*) from customers;
    return next c1;

    open c2 for 
      SELECT customerid, customername
      FROM customers;
    return next c2;

EXCEPTION WHEN OTHERS THEN
    RAISE exception '% %', SQLERRM, SQLSTATE;
END;
$BODY$
LANGUAGE plpgsql;

答案 2 :(得分:0)

在这种情况下对我有用的是使用 JSON 作为返回类型。你的例子:

CREATE OR REPLACE FUNCTION fn_Test()
RETURNS JSON
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN

    INSERT INTO Customers(CustomerName, Address, Area, Phonenumber, Email, communicationpreference)
    VALUES ('Julie Yellow', 'JY Ad', 'JY Ar', 'JV0987654', 'j@ye.com', 1);

    SELECT CustomerId, CustomerName FROM Customers;

    RETURN json_build_object(
        'count', (SELECT COUNT(*) FROM CUSTOMERS),
        'customers', (
            SELECT json_agg(
                json_build_object('customerId', CustomerId, 'customerName', CustomerName)
            ) 
            FROM Customers
        )
    );
EXCEPTION WHEN OTHERS THEN
    RAISE exception '% %', SQLERRM, SQLSTATE;
END;
$BODY$