簡體   English   中英

Postgresql JDBC 表值參數

[英]Postgresql JDBC Table Valued Parameters

MSSQL有一個很棒的特性叫做表值參數 它允許您將自定義數據表傳遞給存儲過程和函數。

我想知道PostgreSQL 中的等價物是什么,如果存在,使用 JDBC? 我知道將數組作為函數參數傳遞的選項,但這似乎僅限於PostgreSQL數據類型。

考慮以下 PL/pgSQL 代碼:

CREATE  TYPE number_with_time AS(
_num   float,
_date  timestamp
);

和這個函數頭:

CREATE OR REPLACE FUNCTION myfunc(arr number_with_time[])

任何人都可以使用 JDBC 驅動程序發布使用用戶定義數據類型數組調用該函數的 Java 代碼嗎?

假設您想從客戶端傳遞值。 如果這些值已經存在於數據庫中,還有其他更簡單的方法。

Composite_type 數組的語法

我知道將數組作為函數參數傳遞的選項,但這似乎僅限於 PostgreSQL 數據類型。

您可以傳遞的內容似乎受到Java Types 和 JDBC Types 的限制,並且似乎沒有對數組類型的規定,更不用說復合值的數組了……

但是,您始終可以傳遞text表示。 我基於兩個基本事實:

  1. 引用手冊

可以創建任何內置或用戶定義的基類型、枚舉類型或復合類型的數組。 尚不支持域數組。

大膽強調我的。 因此,在您創建了問題中定義的類型number_with_time ,或者定義了一個具有相同列的表並自動在系統中注冊行類型后,您還可以使用數組類型number_with_time[]

  1. 每個都有一個text表示。

因此,也有number_with_time[]的文本表示:

'{"(1,2014-04-20 20:00:00)","(2,2014-04-21 21:00:00)"}'::number_with_time[]

函數調用

實際的函數調用取決於函數中定義的返回值 - 這隱藏在您的問題中。

為了避免 JDBC 中數組處理的復雜性,請傳遞text表示。 創建采用text參數的函數。

我不會使用名稱“日期”作為timestamp 使用這個稍微調整的類型定義:

CREATE TYPE number_with_time AS(
   _num float
 , _ts  timestamp
);

簡單的SQL函數:

CREATE OR REPLACE FUNCTION myfunc_sql(_arr_txt text)
  RETURNS integer       -- example
  LANGUAGE sql AS
$func$
   SELECT sum(_num)::int
   FROM   unnest (_arr_txt::number_with_time[]) x
   WHERE  _ts > '2014-04-19 20:00:00';
$func$;

稱呼:

SELECT myfunc_sql('{"(1,2014-04-20 20:00:00)","(2,2014-04-21 21:00:00)"}');

db<> 在這里擺弄
舊的sqlfiddle

演示:

  • 以上 SQL 函數
  • PL/pgSQL 變體
  • 復合類型數組的幾種語法變體
  • 函數調用

像使用簡單的text參數的任何其他函數一樣調用該函數:

CallableStatement myProc = conn.prepareCall("{ ? = call myfunc_sql( ? ) }");
myProc.registerOutParameter(1, Types.VARCHAR);
// you have to escape double quotes in a Java string!
myProc.setString(2, "{\"(1,2014-04-20 20:00:00)\",\"(2,2014-04-21 21:00:00)\"}");
myProc.execute();
String mySum = myProc.getInt(1);
myProc.close(); 

此處的 Postgres JDBC 手冊中的詳細信息。

通過 JDBC 返回整個表的示例:

嘗試這樣的事情:

                ------------------ your connection
                V
Array inArray = conn.createArrayOf("integer", new Integer[][] {{1,10},{2,20}});
stmt.setArray(1, inArray);

可用於構建測試的示例方法:

    public void testInsertMultiDimension() throws Exception {

            Connection c = getConnection();

            PreparedStatement stmt = c.prepareStatement("INSERT INTO sal_emp VALUES ('multi_Bill',?,?);");
            Array intArray = c.createArrayOf("integer", new Integer[] {1000,1000,1000,1000});
            String[][] elements = new String[2][];
            elements[0] = new String[] {"meeting_m","lunch_m"};
            elements[1] = new String[] {"training_m","presentation_m"};

            //Note - although this is a multi-dimensional array, we still supply the base element of the array
            Array multiArray = c.createArrayOf("text", elements);
            stmt.setArray(1, intArray);
            stmt.setArray(2, multiArray);
            stmt.execute();
            //Note - free is not implemented
            //myArray.free();
            stmt.close();
            c.close();
    }

有用的網址:

您的問題是 PostgreSQL 可以使用表或復雜類型作為函數的參數或“表或復雜類型”的數組作為函數的參數? postgresql 全部支持。 當你創建一個表時,它會自動創建一個與表名相同的復雜類型。 喜歡 :

digoal=# create table tbl123(id int, info text);
CREATE TABLE
digoal=# select typname from pg_type  where typname='tbl123';
 typname 
---------
 tbl123
(1 row)

你可以在函數中直接使用這種類型。 對於經驗:

digoal=# create or replace function f_tbl123(i tbl123) returns tbl123 as $$  
  declare
  begin
  return i;
end;
$$ language plpgsql;
CREATE FUNCTION
digoal=# insert into tbl123 values (1,'test'),(2,'test2');
INSERT 0 2
digoal=# select f_tbl123(t) from tbl123 t;
 f_tbl123  
-----------
 (1,test)
 (2,test2)
(2 rows)

該數組也可以在 postgresql 函數中使用。 如果您不知道 Java 中的數組是如何構造的,我認為這個 exp 可以幫助您。

digoal=# select (unnest('{"(1,abc)","(2,ww)"}'::tbl123[])).*;
 id | info 
----+------
  1 | abc
  2 | ww
(2 rows)

digoal=# select '{"(1,abc)","(2,ww)"}'::tbl123[];
        tbl123        
----------------------
 {"(1,abc)","(2,ww)"}
(1 row)
digoal=# select array['(1,abc)','(2,ww)'];
        array         
----------------------
 {"(1,abc)","(2,ww)"}
(1 row)

digoal=# select array['(1,abc)','(2,ww)']::tbl123[];
        array         
----------------------
 {"(1,abc)","(2,ww)"}
(1 row)
digoal=# select (unnest(array['(1,abc)','(2,ww)'])::tbl123).*;
 id | info 
----+------
  1 | abc
  2 | ww
(2 rows)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM