我正在使用带有PostgreSQL中的函数的hibernate来更新数据库中的记录。
以下是PostgreSQL函数,
CREATE OR REPLACE FUNCTION updatesegment(segid bigint, segname text, segdesc text, segmeta text)
RETURNS void AS
$BODY$
BEGIN
UPDATE segment
SET
name = segname,
description = segdesc,
segmentmetadata = segmeta
WHERE
id = segid;
END;
$BODY$
LANGUAGE plpgsql;
在java代码中,我调用了如下函数。
public int updateSegment(Long segmentId, String segName, String segDesc, String segMeta) {
SQLQuery query = (SQLQuery)sessionFactory.getCurrentSession().createSQLQuery("SELECT updatesegment(:segmentId, :segName, :segDesc, :segMeta)")
.setParameter("segmentId", segmentId)
.setParameter("segName", segName)
.setParameter("segDesc", segDesc)
.setParameter("segMeta", segMeta);
int rows = query.executeUpdate();
return rows;
}
当我使用正确的输入参数调用上面的updateSegment()java函数时,DB中的记录会按预期更新。但是query.executeUpdate()总是返回0,因为它应该返回1。
我做错了什么,为什么executeUpdate()不返回1?
提前致谢... !!!
答案 0 :(得分:1)
所以你要调用executeUpdate(),但是传递一个SELECT查询?即使SELECT查询要调用更新行的函数,函数也会更新行,而不是SELECT语句。因此,executeUpdate 1)不会知道要查找更新的行(它是一个SELECT,为什么会更新行?),2)即使知道尝试也无法获取计数。
尝试直接在控制台中运行SELECT语句,看看它是否告诉你它更新了1行......如果这没有告诉你有关行的更新,Hibernate将如何知道?
正如@ dic19所说,如果你想要获得该值,让你的函数返回该值,和使用list()
而不是executeUpdate()
然后拉出该值从结果List
。
答案 1 :(得分:1)
为了在您的函数中获得受影响的行,您需要进行一些更改:
CREATE OR REPLACE FUNCTION updatesegment(segid bigint, segname text, segdesc text, segmeta text)
RETURNS integer AS
$BODY$
DECLARE
rowsAffected integer := 0;
BEGIN
UPDATE segment
SET
name = segname,
description = segdesc,
segmentmetadata = segmeta
WHERE
id = segid;
GET DIAGNOSTICS rowsAffected = ROW_COUNT; --here you get the affected rows
END;
$BODY$
LANGUAGE plpgsql;
然后你也应该相应地修改你的java代码,以执行调用你的函数的SELECT
查询并检索它将返回的整数。
答案 2 :(得分:1)
在PL / PgSQL函数中执行的SQL不会影响rowcount。
如果确实如此,你会如何期望从两个表中删除DELETE的函数然后更新第三个函数?它会返回所有三个行数的总和吗?最后一次操作的行数?什么?
如果您DELETE
表中有一条记录而另一条记录INSERT
,那该怎么办? rowcount是零,一个还是两个?一切都有意义。
如果要使用查询行计数,请不要将查询包装在PL / PgSQL函数中。
如果必须将它们包装在函数中,则需要将行计数提取到GET DIAGNOSTICS
的变量中并返回,例如:
CREATE OR REPLACE FUNCTION updatesegment(segid bigint, segname text, segdesc text, segmeta text, OUT nrows integer)
RETURNS integer AS
$BODY$
BEGIN
UPDATE segment
SET
name = segname,
description = segdesc,
segmentmetadata = segmeta
WHERE
id = segid;
-- store the row count in the nrows OUT parameter
GET DIAGNOSTICS nrows = ROW_COUNT;
END;
$BODY$
LANGUAGE plpgsql;
JDBC不知道这是一个rowcount,它只是一个函数返回值。因此,您必须将其与execute
而不是executeUpdate
一起使用,然后获取结果行以确定受影响的行数。这有点可怕;除非你需要SECURITY DEFINER
,否则我很难想象你为什么要通过一个函数来做这件事。
目前无法设置函数的rowcount结果。