Postgres:将自定义类型从Java传递到Postgres函数
我有一个postgres函数,它接受一个复杂的用户定义类型作为输入Postgres:将自定义类型从Java传递到Postgres函数,java,postgresql,plpgsql,Java,Postgresql,Plpgsql,我有一个postgres函数,它接受一个复杂的用户定义类型作为输入 CREATE OR REPLACE FUNCTION addUser(user IN O_USER) RETURNS VOID AS $$ BEGIN end; $$ language plpgsql; CREATE TYPE O_USER AS ( id NUMERIC, name VARCHAR(50), addresses O_ADDRESS[] ); CREATE TYPE O_ADDRESS AS
CREATE OR REPLACE FUNCTION addUser(user IN O_USER) RETURNS VOID
AS
$$
BEGIN
end;
$$ language plpgsql;
CREATE TYPE O_USER AS (
id NUMERIC,
name VARCHAR(50),
addresses O_ADDRESS[]
);
CREATE TYPE O_ADDRESS AS (
id NUMERIC,
city VARCHAR(50)
);
现在我需要从Java调用这个函数。
我的理解是,我需要传递一个字符串,该字符串将由db类型转换到UDT
当我传递没有地址的用户时,它工作正常。但是如果我也传递了地址数组,那么它就给出了错误
ERROR: malformed array literal: "{(1"
DETAIL: Unexpected end of input.
SQL state: 22P02
Character: 23
我也可以用postgres select语句重现这个问题。例如,下面的工作很好
Select * from addUser('(1, "Vishal", {})');
但是当我传递地址时,那就是个问题
Select * from addUser('(1, "Vishal", {(1,"tet")})');
Select * from addUser('(1, "Vishal", {"(1,)"})');
Select * from addUser('(1, "Vishal", {"(1,null)"})')
我相信我不能正确地构造字符串。你知道这里怎么了吗
更新
调用函数的Java代码
import org.springframework.jdbc.core.SqlParameter;
import org.springframework.jdbc.object.StoredProcedure;
import javax.sql.DataSource;
import java.sql.Types;
import java.util.HashMap;
import java.util.Map;
public class AddUserProcedurePostgres extends StoredProcedure {
public AddUserProcedurePostgres(DataSource dataSource) {
super(dataSource, "addUser");
setFunction(true);
declareParameter(new SqlParameter("i_User", Types.OTHER, "O_USER"));
compile();
}
public void execute() {
Map<String, Object> input = new HashMap<>();
input.put("i_User", "(1, Vishal, array[(1,tet)]::O_ADDRESS[])");
execute(input);
}
}
您需要使用
array
literal传递O\u地址
数组,并将数组键入O\u地址[]
。以下select
语句有效
select * from addUser(cast(row(1, 'Vishal', array[cast(row(1,'tet') as O_ADDRESS)]) as O_USER));
select * from addUser((1, 'Vishal', array[]::O_ADDRESS[])::O_USER);
select * from addUser((1, 'Vishal', array[]::O_ADDRESS[]));
select * from addUser((1, 'Vishal', array[(1,'tet')]::O_ADDRESS[]));
我找到了两种将所需值传递给函数的方法:
我选择第二种方法,因为它易于维护。感谢@Rahul Sharma的回复。正如我所说,我需要从Java调用函数。不确定如何从Java代码中传递数组文本。您只需要从代码中构建字符串。不知道问题在哪里。可能,您可以显示一些代码,其中您正在生成查询并且在构建字符串时遇到困难。我已在问题中添加了Java代码,用于调用函数。首先修改此字符串
“(1,Vishal,array[(1,tet)]::O_ADDRESS[])”
到“(1,'Vishal',array[(1,'tet')::O_ADDRESS[])”
。在代码将查询转换为字符串之前,尝试添加日志,并查看生成的字符串是什么。我按照建议更改了参数,但出现了相同的错误。参数是(1,'Vishal',array[(1,'tet')]::O_ADDRESS[])
,查询结果是select*from addUser(?)
select * from addUser(cast(row(1, 'Vishal', array[cast(row(1,'tet') as O_ADDRESS)]) as O_USER));
select * from addUser((1, 'Vishal', array[]::O_ADDRESS[])::O_USER);
select * from addUser((1, 'Vishal', array[]::O_ADDRESS[]));
select * from addUser((1, 'Vishal', array[(1,'tet')]::O_ADDRESS[]));