0

我正在使用带有 PostgreSQL 中的函数的休眠来更新数据库中的记录。

以下是 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 函数时,数据库中的记录会按预期更新。但是 query.executeUpdate() 总是返回 0,而它应该返回 1。

我在做什么错,为什么 executeUpdate() 不返回 1?

提前致谢...!!!

4

3 回答 3

2

所以你调用了executeUpdate(),但是传递了一个SELECT查询?即使该 SELECT 查询将调用您的函数来更新行,该函数也会更新行,而不是 SELECT 语句。因此,executeUpdate 1) 不会知道查找更新的行(它是一个 SELECT,为什么要更新行?),并且 2) 即使它知道尝试也无法获得计数。

尝试直接在控制台中运行您的 SELECT 语句,看看它是否告诉您它更新了 1 行...如果它没有告诉您正在更新的行,那么 Hibernate 怎么知道?

正如@dic19 所说,如果您想取回该值,请让您的函数返回该值,然后使用list()而不是executeUpdate()然后从结果中提取该值List

于 2013-08-08T18:11:40.260 回答
2

为了在您的函数中获得受影响的行,您需要进行一些更改:

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调用您的函数的查询并检索它将返回的整数。

资料来源: PostreSQL 文档

于 2013-08-08T18:49:59.827 回答
2

在 PL/PgSQL 函数中执行的 SQL 不会影响行数。

如果是这样,您如何期望从两个表中删除然后更新第三个工作的函数?它会返回所有三个行数的总和吗?最后一次操作的行数?什么?

如果您DELETE从一个表中记录一个记录而INSERT另一个记录呢?行数是零、一还是二?一切都会说得通。

如果要使用查询行数,请不要将查询包装在 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 不知道这是一个行数,它只是一个函数返回值。因此,您必须将其与executenot一起使用executeUpdate,然后获取结果行以确定受影响的行数。这有点可怕;除非你需要SECURITY DEFINER我很难想象你为什么要通过一个函数来做这件事。

当前无法设置函数的行计数结果。

于 2013-08-09T02:03:50.960 回答