假设您想从客户端传递值。如果这些值已经存在于数据库中,那么有其他更简单的方法。
array of composite_type 的语法
我知道可以将数组作为函数参数进行传递,但似乎仅限于 PostgreSQL 数据类型。
您可以传递的内容似乎受到
Java Types and JDBC Types 的限制,并且似乎没有为数组类型提供规定,更不用说复合值的数组了…
然而,您总是可以传递
text
表示。我基于两个基本事实进行构建:
引用
手册:
任何内置或用户定义的基本类型、枚举类型或复合类型的数组均可创建。尚不支持域的数组。
加粗部分是我强调的。因此,在你创建了在问题中定义的类型
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
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<>fiddle 这里
旧版 sqlfiddle
演示:
- 上述 SQL 函数
- PL/pgSQL 变体
- 有关复合类型数组的一些语法变体
- 函数调用
像调用其他简单 text
参数函数一样调用该函数:
CallableStatement myProc = conn.prepareCall("{ ? = call myfunc_sql( ? ) }");
myProc.registerOutParameter(1, Types.VARCHAR);
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返回整个表的示例:
SELECT * FROM unnest(arr)
(尽管这可能不是最节省内存的方式)。 - pozsARRAY[(1, 'now'), (2, 'now')]::number_with_time[]
- 或者从结果集中创建一个数组,使用array_agg(("float_val", "timestamp_val")::number_with_time)
。 - pozs"... ARRAY[(?, ?), (?, ?)]::number_with_time[] ..."
即可。http://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html - pozs