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代码,使用用户定义数据类型的数组调用该函数吗?
答案 0 :(得分:5)
假设您想从客户端传递值。如果数据库中已存在值,则还有其他更简单的方法......
我知道将数组作为函数参数传递的选项,但是 这似乎仅限于PostgreSQL数据类型。
你可以传递的内容似乎受到Java Types and JDBC Types的限制,并且似乎没有规定数组类型,更不用说复合值数组......
但是,您始终可以传递text
表示。我基于两个基本事实:
任何内置或用户定义的基类型的枚举,枚举类型,或 可以创建复合类型。尚不支持域的数组。
大胆强调我的。因此,在您创建问题中定义的类型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演示了:
像使用简单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)