[英]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 代碼嗎?
假設您想從客戶端傳遞值。 如果這些值已經存在於數據庫中,還有其他更簡單的方法。
我知道將數組作為函數參數傳遞的選項,但這似乎僅限於 PostgreSQL 數據類型。
您可以傳遞的內容似乎受到Java Types 和 JDBC Types 的限制,並且似乎沒有對數組類型的規定,更不用說復合值的數組了……
但是,您始終可以傳遞text
表示。 我基於兩個基本事實:
可以創建任何內置或用戶定義的基類型、枚舉類型或復合類型的數組。 尚不支持域數組。
大膽強調我的。 因此,在您創建了問題中定義的類型number_with_time
,或者定義了一個具有相同列的表並自動在系統中注冊行類型后,您還可以使用數組類型number_with_time[]
。
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)"}');
演示:
像使用簡單的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();
通過 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.