2

I have updatable view on PostgreSQL server.

Update query works fine when I execute it from pgAnmin3 console, but when I try to update this view with ResultSet.updateRow() method, I get the following error:

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

I guess I can't specify primary key for view.

Can I specify key columns for ResultSet.updateRow() method in my client application? Or can I specify a WHERE clause for ResultSet.updateRow() method?

Here are my tables

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;

This insert statement works fine

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

But the problem with this java code

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();
4

1 回答 1

2

问题是您正在查询一个视图,而该视图没有主键(我不确定 PostgreSQL 是否可以做到这一点,但大多数数据库不支持)。JDBC 驱动程序需要一个主键才能使结果集可更新。

换句话说:您无法通过结果集更新此视图。您要么需要使用显式UPDATE语句,要么直接在基础表上执行此操作,而不是通过视图。

于 2015-04-28T07:15:29.960 回答