选择失败后插入

时间:2018-11-26 15:20:36

标签: postgresql stored-procedures

我想建立一个netchange,每次阅读新记录时,都应在单独的记录中设置新的时间戳。因此,每次阅读记录时,我只会得到新记录。但是我无法在存储过程中读取后进行插入。我收到错误ERROR:声明要返回项目的函数中的返回类型不匹配。第一次选择的记录不返回。我不能先删除插入内容,因为那样我将再也没有数据。

我的程序。

CREATE OR REPLACE FUNCTION getitems() RETURNS SETOF items 
AS $$  
  select * 
  from items 
  where insertdate > (select lastread 
                      from lastread 
                      ORDER BY lastread DESC LIMIT 1 );
  INSERT into LASTREAD (LASTREAD) VALUES (current_timestamp);
$$ LANGUAGE SQL;

2 个答案:

答案 0 :(得分:0)

您可以创建一个临时表并在函数中使用它。

CREATE TEMP TABLE temp_lastread ( lastread TIMESTAMP ) ON COMMIT DELETE ROWS;

CREATE OR REPLACE FUNCTION getitems() RETURNS
SETOF items AS $$

TRUNCATE TABLE temp_lastread;
INSERT INTO temp_lastread (lastread)
                SELECT lastread
                        FROM lastread
                      ORDER BY lastread DESC LIMIT 1;
INSERT into LASTREAD (LASTREAD) VALUES (current_timestamp);
select *
  from items
  where insertdate > ( select lastread FROM temp_lastread );
$$ LANGUAGE SQL

答案 1 :(得分:0)

您可以将INSERT作为第一个语句,并根据current_timestamp签入子选择。

这利用了一个事实,即current_timestamp在事务处理期间不会前进,这意味着current_timestamp语句中insert的值将与交易中使用的值完全相同。子选择。

您还可以使用max()函数来简化where条件:

CREATE OR REPLACE FUNCTION getitems() 
  RETURNS SETOF items 
AS $$  
  INSERT into LASTREAD (LASTREAD) VALUES (current_timestamp);
  select * 
  from items 
  where insertdate > (select max(lastread)
                      from lastread
                      where lastread <> current_timestamp);
$$ LANGUAGE SQL;

如果lastread表中没有值,则以上操作将无效。可以通过在coalesce()函数上使用max()来解决此问题(order by limit方法无法做到这一点:

CREATE OR REPLACE FUNCTION getitems() 
  RETURNS SETOF items 
AS $$  
  INSERT into LASTREAD (LASTREAD) VALUES (current_timestamp);
  select * 
  from items 
  where insertdate > (select coalesce(max(lastread), '-infinity')
                      from lastread
                      where lastread <> current_timestamp);
$$ LANGUAGE SQL;

在线示例:https://rextester.com/RJA35651