Postgresql JDBC表值参数

MSSQL有一个很棒的function叫做Table Valued Parameters 。 它允许您将自定义数据表传递给存储过程和函数。

我想知道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类型和JDBC类型的限制 ,并且似乎没有规定数组类型,更不用说复合值数组……

但是,您始终可以传递text表示。 我基于两个基本事实:

1) 每份文件:

可以创建任何内置或用户定义的基类型,枚举类型或复合类型的数组。 尚不支持域的数组。

大胆强调我的。 因此,在创建了问题中定义的类型number_with_time之后 – 或者定义了具有相同列的表(自动在系统中注册相应的复合类型)之后,您还可以自动使用数组类型number_with_time[]

2) 每个都有一个text表示。

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

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

函数调用

实际的函数调用取决于函数中定义的返回值 – 这在您的问题中隐藏。

为避免JDBC中数组处理的复杂性,请传递text表示。 使用text参数创建函数。

我不打算使用名称“date”作为timestamp 。 使用此略微调整的类型定义:

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

简单的SQL函数:

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

呼叫:

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

这个SQL小提琴演示:

  • 以上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返回整个表的示例:
从PL / pgSQL函数返回行

尝试这样的事情:

  ------------------ 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(); } 

有用的url:

  • 绑定参数为PostgreSQL数组
  • JDBC中的Postgres和多维数组
  • 将数组从Java传递到Postgres

你的问题是PostgreSQL可以使用表或复杂类型作为函数的参数或“表或复杂类型”的数组作为函数的参数吗? postgresql所有支持。 当你创建一个表时,它会自动创建一个名为tablename的复杂类型。 喜欢 :

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

你可以直接在函数中使用这种类型。 对于exp:

 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)