2015-04-27 1 views
2

У меня есть обновляемый вид на сервере PostgreSQL.Обновление строк обновляемого представления с помощью функции ResultSet.updateRow

Update запрос отлично работает, когда я исполняю его от pgAnmin3 консоли, но когда я пытаюсь обновить эту точку зрения с ResultSet.updateRow() метод, я получаю следующее сообщение об ошибке:

org.postgresql.util.PSQLException: No primary key found for table

Я предполагаю, что я не могу указать первичный ключ для просмотра.

Могу ли я указать ключевые столбцы для метода ResultSet.updateRow() в моем клиентском приложении? Или я могу указать предложение WHERE для метода ResultSet.updateRow()?

Вот мои таблицы

CREATE TABLE fin.t_year 
(
    id serial NOT NULL, 
    date_begin date NOT NULL, 
    date_end date NOT NULL, 
    year_name character varying(128), 
    CONSTRAINT "PK_year" PRIMARY KEY (id) 
) 

WITH (
    OIDS=FALSE 
); 


CREATE TABLE fin.t_period 
(
    id serial NOT NULL, 
    id_year integer NOT NULL, 
    per_begin date NOT NULL, 
    per_end date NOT NULL, 
    per_name character varying(256), 
    CONSTRAINT "PK_period" PRIMARY KEY (id), 
    CONSTRAINT "FK_period_year" FOREIGN KEY (id_year) 
    REFERENCES fin.t_year (id) MATCH SIMPLE 
    ON UPDATE NO ACTION ON DELETE NO ACTION 
) 

WITH (
    OIDS=FALSE 
); 


CREATE VIEW fin.vi_period AS 
    SELECT per.id, 
     per.per_begin AS "Begin", 
     per.per_end AS "End", 
     per.per_name AS "Name", 
     y.year_name AS "Year" 
     FROM fin.t_period per 
     JOIN fin.t_year y ON y.id = per.id_year; 



CREATE OR REPLACE FUNCTION fin.tgfn_vi_period_update() 
RETURNS trigger AS 
$BODY$ 
    DECLARE 
     id_row INTEGER; 
     id_curr INTEGER; 
     result RECORD; 
BEGIN 
     id_curr = NEW.id; 

     -- Replace text identifier with integer primary key 
     IF NEW."Year" IS NOT NULL THEN 

      SELECT id INTO id_row 
       FROM fin.t_year 
       WHERE year_name = NEW."Year"; 
      UPDATE fin.t_period SET id_year = id_row 
       WHERE id = id_curr; 

     END IF; 


     IF NEW."Begin" IS NOT NULL THEN  

      UPDATE fin.t_period SET per_begin = NEW."Begin" 
       WHERE id = id_curr; 
     END IF; 
     IF NEW."End" IS NOT NULL THEN  

      UPDATE fin.t_period SET per_end = NEW."End" 
       WHERE id = id_curr; 
     END IF; 
     IF NEW."Name" IS NOT NULL THEN 
      UPDATE fin.t_period SET per_name = NEW."Name" 
       WHERE id = id_curr; 
     END IF; 



     SELECT * INTO result FROM fin.vi_period WHERE id = id_curr; 
     RETURN result; 

END; 
$BODY$ 
LANGUAGE plpgsql VOLATILE 
    COST 100; 

Эта вставка оператор работает отлично

UPDATE fin.vi_period SET "Year" = 'new_year_name' WHERE id = 10; 

Но проблема с этим Java код

statement = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); 
ResultSet rs = statement.ExecuteQuery("SELECT * FROM fin.vi_period;"); 


rs.absolute(pos + 1); 
rs.updateString("new_year_name"); 
rs.updateRow(); 
+0

Можете ли вы представить структуру таблицы и инструкцию sql, которые вы используете для обновления таблицы. – Blip

ответ

1

Проблема заключается в том, что вы запрашиваете вид , и этот вид не имеет первичного ключа (я не уверен, что это возможно даже с PostgreSQL, но большинство база данных не поддерживает это). Драйвер JDBC требует, чтобы первичный ключ мог сделать обновляемый набор результатов.

Другими словами: вы не можете обновить этот вид через результирующий набор. Вам нужно либо использовать явный оператор UPDATE, либо сделать это непосредственно в базовой таблице, а не через представление.