Java 根据外部表的最后一个条目插入记录

Java 根据外部表的最后一个条目插入记录,java,sql,postgresql,postgresql-9.5,Java,Sql,Postgresql,Postgresql 9.5,我有以下简单的表关系: CREATE TABLE PRODUCT ( ID BIGSERIAL, TYPE VARCHAR(24), TITLE VARCHAR(128), PRIMARY KEY (ID) ); CREATE TABLE EVENT ( ID BIGSERIAL, STATE VARCHAR(64) NOT NULL,

我有以下简单的表关系:

CREATE TABLE PRODUCT (
  ID                BIGSERIAL,
  TYPE              VARCHAR(24),
  TITLE             VARCHAR(128),
  PRIMARY KEY (ID)
);

CREATE TABLE EVENT (
  ID               BIGSERIAL,
  STATE            VARCHAR(64) NOT NULL,
  DATETIME         TIMESTAMP   NOT NULL,
  PRODUCT_ID        BIGINT,
  FOREIGN KEY (PRODUCT_ID) REFERENCES PRODUCT(ID),
  PRIMARY KEY (ID)
);
事件中的“状态”是从Java枚举转换而来的,可以是:初始化、可用、处理等

我希望执行以下操作:如果产品的最后一个事件条目的状态为“已处理”,则在事件表中创建一个状态为“可用”的新插入。这必须适用于所有产品

如您所见,事件表引用了product。我看过:

但是我想不出来

INSERT INTO EVENT( STATE, DATETIME, PRODUCT_ID )
SELECT 'AVAILABLE', current_timestamp, product_id
FROM EVENT e
WHERE PRODUCT_ID = 123
  AND e.STATE = 'PROCESSED'
  AND NOT EXISTS (
     SELECT 'anything' FROM event e1
     WHERE e1.PRODUCT_ID = e.PRODUCT_ID
       AND e1.DATETIME > e.DATETIME
);

如果该命令应在多线程/多用户环境中运行,则整个事务必须由这四个命令组成,否则可能会出现重复记录:

BEGIN TRANSACTION;

/* lock the parent record */
PERFORM id FROM PRODUCT WHERE id = 123 FOR UPDATE;

INSERT INTO EVENT( STATE, DATETIME, PRODUCT_ID )
    SELECT 'AVAILABLE', current_timestamp, product_id
    FROM EVENT e
    WHERE PRODUCT_ID = 123
      AND e.STATE = 'PROCESSED'
      AND NOT EXISTS (
         SELECT 'anything' FROM event e1
         WHERE e1.PRODUCT_ID = e.PRODUCT_ID
           AND e1.DATETIME > e.DATETIME
    );

COMMIT;

如果按顺序插入数据,我更倾向于使用
id
进行比较,如下所示:

insert into event (state, datetime, product_id)
    select 'AVAILABLE', current_timestamp, product_id
    from event e
    where e.state = 'PROCESSED' and
          not exists (select e2.state
                      from event e2
                      where e2.product_id = e.product_id and
                            e2.id > e.id  -- you can use timestamp
                     );
我更感兴趣的是,你说过
state
是一个
enum
。博士后确实支持,但你没有。但是,您要执行的操作通常使用检查约束进行处理:

CREATE TABLE EVENT (
  ID               BIGSERIAL,
  STATE            VARCHAR(64) NOT NULL,
  DATETIME         TIMESTAMP   NOT NULL,
  PRODUCT_ID        BIGINT,
  FOREIGN KEY (PRODUCT_ID) REFERENCES PRODUCT(ID),
  PRIMARY KEY (ID),
  CONSTRAINT CHECK_EVENT_STATE CHECK (STATE IN ('INITIALIZED', 'AVAILABLE', 'PROCESSED'))
);

太好了,正是我想要的!!数据插入是顺序的,我对枚举的意思是Java枚举。我更新了帖子。再次感谢!谢谢你的回答。戈登·林诺夫的回答正是我想要的。