Postgresql

從函式返回帶有列名的 ResultSet

  • January 19, 2018

我有以下 postgresql 函式:

CREATE OR REPLACE FUNCTION readMessage(messageFor INT, qid INT = NULL, ctxt INT = NULL, messageFrom INT = NULL, byTimeStamp BOOLEAN = FALSE)
RETURNS SETOF message
AS $$
DECLARE
   sql varchar;
BEGIN
   sql := 'SELECT * FROM message WHERE (receiver_id IS NULL OR receiver_id = $1)';
   IF qid IS NOT NULL THEN
       sql := sql || ' AND queue_id = $2';
   END IF;
   IF ctxt IS NOT NULL THEN
       sql := sql || ' AND context = $3';
   ELSE
       sql := sql || ' AND context IS NULL';
   END IF;

   IF $4 IS NOT NULL THEN
       sql := sql || ' AND sender_id = $4';
   END IF;

   sql := sql || ' ORDER BY';
   IF byTimeStamp THEN
       sql := sql || ' arrive_time ASC';
   ELSE
       sql := sql || ' priority DESC';
   END IF;

   sql := sql || ' LIMIT 1'; 
   RETURN QUERY EXECUTE sql
   USING messageFor, qid, ctxt, messageFrom;
END;
$$
LANGUAGE plpgsql;

現在,上面的函式工作正常,但結果集不包含列名(例如:一個簡單的 SELECT 語句返回帶有列名的結果)。我需要能夠在 Java 程式碼中訪問上述函式的結果,如下所示:

Connection con;
PreparedStatement ps = con.prepareStatement("select readMessage(1, 1, 1, 1, true))";
ResultSet rs = ps.executeQuery(); 
rs.getInt(<column-name>) 

代替

rs.getInt(<column-index>)

以獲得更易讀的程式碼。如何修改我的 postgresql FUNCTION 來實現這一點?

考慮下面的例子:

CREATE TABLE test.child (
   id    integer,
   p_id1 integer,
   p_id2 integer
);

CREATE OR REPLACE FUNCTION named_cols() 
RETURNS SETOF test.child 
AS $$
 SELECT 0, 12, 23;                                                                                                                                                                                                 
$$ LANGUAGE sql;

SELECT named_cols();
named_cols 
────────────
(0,12,23)


SELECT * FROM named_cols();
id │ p_id1 │ p_id2 
────┼───────┼───────
 0 │    12 │    23

如果您以第一種方式呼叫該函式,您將返回一條記錄,但沒有列名。看起來你在第二個之後 - 你會在任何程式語言中遇到相同的行為,而不僅僅是 Java。

引用自:https://dba.stackexchange.com/questions/52377