无法使用可调用语句或准备好的语句调用 PostgreSQL 函数
Unable to call a PostgreSQL function using callable statement or prepared statement
我创建了一个 PostgreSQL 函数,该函数在后端进行了测试,并且按预期工作。但是,当我尝试通过 Scala 模块调用它时,它说该函数不存在。
Function
:
create or replace function testing.compareData(ab integer, b json, tablename varchar) RETURNS void as $$
DECLARE
actualTableName varchar := tablename;
histTableName varchar:= actualTableName ||'_hist';
job_id Integer:=0;
begin --<<<< HERE
set search_path to testing; -- Set the schema name
execute 'SELECT id FROM '||actualTableName||' WHERE id =' into job_id using ab;
-- if there is data for id in the table then perform below operations
if job_id is not null then
execute FORMAT('INSERT INTO %I select * from %I where id = ',histTableName,actualTableName) USING ab;
execute FORMAT('DELETE FROM %I where id = ',actualTableName) USING ab;
EXECUTE FORMAT('INSERT INTO %I values(,)',actualTableName) USING ab,b;
-- if id is not present then create a new record in the actualTable
ELSE
EXECUTE FORMAT('INSERT INTO %I values(,)',actualTableName) USING ab,b;
END IF;
END; --<<<< END HERE
$$ LANGUAGE plpgsql;
Callable Statement
方式:
def callingStoredProcedure(message: String, id: Integer, resourceType: String): Unit = {
val connectionUrl: String = ReadingConfig.postgreDBDetails().get("url").getOrElse("None")
var conn: Connection = null
var callableStatement: CallableStatement = null
try {
conn = DriverManager.getConnection(connectionUrl)
callableStatement = conn.prepareCall("{ call testing.compareData( ?,?,? ) }")
callableStatement.setString(1, message)
callableStatement.setInt(2, id)
callableStatement.setString(3, resourceType)
callableStatement.execute()
} catch {
case up: Exception =>
throw up
} finally {
conn.close()
}
}
Prepared Statement
方式:
def callDataCompareAndInsertFunction(message: String, id: Integer, resourceType: String): Unit = {
val connectionUrl: String = ReadingConfig.postgreDBDetails().get("url").getOrElse("None")
var pstmt: PreparedStatement = null
var conn: Connection = null
try {
conn = DriverManager.getConnection(connectionUrl)
pstmt = conn.prepareStatement("select testing.compareData(?,?,?)")
pstmt.setInt(1, id)
pstmt.setString(2, message)
pstmt.setString(3, resourceType)
pstmt.executeQuery()
}
catch {
case e: Exception => throw e
}
finally {
conn.close()
}
}
这里,testing
是我创建函数的模式。当 运行 使用两种方式时,它会抛出以下错误:
Exception in thread "main" org.postgresql.util.PSQLException: ERROR: function testing.comparedata(character varying, integer, character varying) does not exist
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
您的第一个参数不是字符串,因此调用 setString(1, ...)
将导致您在问题中引用的错误。
您的第二个参数声明为 json
,因此您也不能直接向其中传递字符串值。以下应该有效(给定函数定义):
pstmt = conn.prepareStatement("select testing.compareData(?,cast(? as json),?)")
pstmt.setInt(1, id)
pstmt.setString(2, message)
pstmt.setString(3, resourceType)
您可能还需要使用 pstmt.execute()
而不是 executeQuery()
,因为您的函数没有 return 任何东西。
我创建了一个 PostgreSQL 函数,该函数在后端进行了测试,并且按预期工作。但是,当我尝试通过 Scala 模块调用它时,它说该函数不存在。
Function
:
create or replace function testing.compareData(ab integer, b json, tablename varchar) RETURNS void as $$
DECLARE
actualTableName varchar := tablename;
histTableName varchar:= actualTableName ||'_hist';
job_id Integer:=0;
begin --<<<< HERE
set search_path to testing; -- Set the schema name
execute 'SELECT id FROM '||actualTableName||' WHERE id =' into job_id using ab;
-- if there is data for id in the table then perform below operations
if job_id is not null then
execute FORMAT('INSERT INTO %I select * from %I where id = ',histTableName,actualTableName) USING ab;
execute FORMAT('DELETE FROM %I where id = ',actualTableName) USING ab;
EXECUTE FORMAT('INSERT INTO %I values(,)',actualTableName) USING ab,b;
-- if id is not present then create a new record in the actualTable
ELSE
EXECUTE FORMAT('INSERT INTO %I values(,)',actualTableName) USING ab,b;
END IF;
END; --<<<< END HERE
$$ LANGUAGE plpgsql;
Callable Statement
方式:
def callingStoredProcedure(message: String, id: Integer, resourceType: String): Unit = {
val connectionUrl: String = ReadingConfig.postgreDBDetails().get("url").getOrElse("None")
var conn: Connection = null
var callableStatement: CallableStatement = null
try {
conn = DriverManager.getConnection(connectionUrl)
callableStatement = conn.prepareCall("{ call testing.compareData( ?,?,? ) }")
callableStatement.setString(1, message)
callableStatement.setInt(2, id)
callableStatement.setString(3, resourceType)
callableStatement.execute()
} catch {
case up: Exception =>
throw up
} finally {
conn.close()
}
}
Prepared Statement
方式:
def callDataCompareAndInsertFunction(message: String, id: Integer, resourceType: String): Unit = {
val connectionUrl: String = ReadingConfig.postgreDBDetails().get("url").getOrElse("None")
var pstmt: PreparedStatement = null
var conn: Connection = null
try {
conn = DriverManager.getConnection(connectionUrl)
pstmt = conn.prepareStatement("select testing.compareData(?,?,?)")
pstmt.setInt(1, id)
pstmt.setString(2, message)
pstmt.setString(3, resourceType)
pstmt.executeQuery()
}
catch {
case e: Exception => throw e
}
finally {
conn.close()
}
}
这里,testing
是我创建函数的模式。当 运行 使用两种方式时,它会抛出以下错误:
Exception in thread "main" org.postgresql.util.PSQLException: ERROR: function testing.comparedata(character varying, integer, character varying) does not exist
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
您的第一个参数不是字符串,因此调用 setString(1, ...)
将导致您在问题中引用的错误。
您的第二个参数声明为 json
,因此您也不能直接向其中传递字符串值。以下应该有效(给定函数定义):
pstmt = conn.prepareStatement("select testing.compareData(?,cast(? as json),?)")
pstmt.setInt(1, id)
pstmt.setString(2, message)
pstmt.setString(3, resourceType)
您可能还需要使用 pstmt.execute()
而不是 executeQuery()
,因为您的函数没有 return 任何东西。