Вставить после неудачного выбора - PullRequest
0 голосов
/ 26 ноября 2018

Я хочу создать сеть обмена, и каждый раз, когда я читаю новые записи, новая отметка времени должна быть установлена ​​в отдельной записи.Поэтому каждый раз, когда я читаю записи, я получаю только новые.Но я не могу сделать вставку после чтения в хранимой процедуре.Я получаю ошибку 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 голосов
/ 26 ноября 2018

Вы можете сделать INSERT первым оператором и проверить в подвыборе current_timestamp.

Это использует тот факт, что current_timestamp не продвигается во время транзакции, что означает, что значение для current_timestamp в операторе insert будет точно таким же, как значение, используемое в суб-выборе,

Вы также можете упростить условие «где», используя функцию max():

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

0 голосов
/ 26 ноября 2018

Вы можете создать временную таблицу и использовать ее в функции.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...