2013-08-08 4 views
0

Я использую hibernate с функцией в PostgreSQL для обновления записи в БД.Hibernate executeUpdate() для функции 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; 
} 

Когда я вызвать функцию Java updateSegment() выше с правильными входными параметрами, запись в БД обновляется, как ожидалось. Но query.executeUpdate() всегда возвращает 0, где он должен возвращаться.

Что я делаю неправильно и почему не выполняетUpdate() возвращает 1?

Заранее спасибо ... !!!

+0

Итак, вы вызываете executeUpdate(), но передаете ему запрос SELECT? Похоже, возможно, это ваша проблема ... – Tim

+0

Мне нужен SELECT, чтобы вызвать функцию plpgsql. В противном случае я не могу вызывать функцию в БД .. и внутри функции plpgsql есть инструкция обновления. –

ответ

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 запроса вызова вашей функции и получить целое число будет возвращено.

Источник:PostreSQL Documentation

1

Итак, вы вызываете executeUpdate(), но передаете ему запрос SELECT? Даже если этот запрос SELECT будет вызывать вашу функцию, которая обновляет строки, функция обновляет строки, а не инструкцию SELECT. Так что executeUpdate 1) не собирается знать обновленные строки (это SELECT, зачем было обновлять строки?) И 2) не смог бы получить счет, даже если бы он знал, что попробовать.

Попробуйте запустить инструкцию SELECT непосредственно в консоли и посмотрите, сообщит ли он вам, что она обновила 1 строку ... Если это не говорит вам о обновляемых строках, то как Hibernate знает?

Как @ dic19 говорит, если вы хотите, чтобы получить это значение обратно, есть ваша функция возвращает это значение, и использование list() вместо executeUpdate() и затем тянуть это значение из полученного List.

+0

Как я могу сохранить обновить инструкцию внутри функции и по-прежнему получить строку, затронутую функцией внутри java .. Это мое требование .. спасибо .. –

+0

@BathiyaPriyadarshana В настоящее время ваша функция возвращает 'void'. Заставьте его возвратить количество обновленных строк. Тогда ваш 'SELECT', вызванный из java, получит обновленный номер строки. – dic19

1

SQL выполняется внутри функций PL/PgSQL не влияет на сверку.

Если бы это было так, как бы вы ожидали функции, которая DELETEd из двух таблиц, то UPDATEd третьей работы? Будет ли он возвращать сумму всех трех рядов? Строка последней операции? Какие?

Как насчет вас 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.

Смежные вопросы