Postgresql JDBC表值参数

时间:2014-04-11 09:41:17

标签: java arrays postgresql jdbc plpgsql

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代码,使用用户定义数据类型的数组调用该函数吗?

3 个答案:

答案 0 :(得分:5)

假设您想从客户端传递值。如果数据库中已存在值,则还有其他更简单的方法......

composite_type

数组的语法
  

我知道将数组作为函数参数传递的选项,但是   这似乎仅限于PostgreSQL数据类型。

你可以传递的内容似乎受到Java Types and JDBC Types的限制,并且似乎没有规定数组类型,更不用说复合值数组......

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

1)Per documentation:

  

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

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

2)每个值都有 number_with_time[] 表示。

因此,text还有一个文本表示:

number_with_time[]

函数调用

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

为避免JDBC中数组处理的复杂化,请传递'{"(1,2014-04-20 20:00:00)","(2,2014-04-21 21:00:00)"}'::number_with_time[] 表示。使用text参数创建函数。

我不会使用这个名字" date"对于text。使用这个稍微调整过的类型定义:

timestamp

简单的SQL函数:

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

呼叫:

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;

SQL Fiddle演示了:

  • 以上SQL函数
  • PL / pgSQL变体
  • 复合类型
  • 数组的几种语法变体
  • 函数调用。

像使用简单SELECT myfunc_sql('{"(1,2014-04-20 20:00:00)","(2,2014-04-21 21:00:00)"}'); 参数的任何其他函数一样调用该函数:

text

Details in the Postgres JDBC manual here.

通过JDBC返回整个表的示例:
Return rows from a PL/pgSQL function

答案 1 :(得分:1)

尝试这样的事情:

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

有用的链接:

答案 2 :(得分:0)

你的问题是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)