2016-12-18 7 views
1

У меня есть таблица watchers:Postgres пользовательская функция с ДЕЛУ

------------------------------------------ 
time_type | time_count | timestamp_created 
------------------------------------------ 
    'hour' | 1  | 2016-12-08 15:56:26.169614 
    'hour' | 13  | ... 
    'day' | 5  | ... 

Я стараюсь, чтобы получить целое число на основе time_type и time_count значения:

CREATE OR REPLACE FUNCTION af_calculate_range(tt text,tc integer) RETURNS integer AS $$ 
      SELECT tt, CASE tt WHEN 'day' THEN tc * 60 * 60 
           WHEN 'hour' THEN tc * 60 
         END 
     FROM watchers; 

      $$ 
    LANGUAGE SQL; 

SELECT af_calculate_range(time_type, time_count) FROM watchers 

, но я получаю сообщение об ошибке:

ERROR: return type mismatch in function declared to return integer 
DETAIL: Final statement must return exactly one column. 
CONTEXT: SQL function "af_calculate_range" 
********** Error ********** 

Использование:

SELECT * FROM watchers 
WHERE EXTRACT(EPOCH FROM now()) > (EXTRACT(EPOCH FROM timestamp_created) + 
af_calculate_range(time_type, time_count)) 

, если time_type = 'hour' и time_count = 1 вывод должен быть 3600 секунд.

Что случилось с моим, например:

я использовал https://www.postgresql.org/docs/7.4/static/functions-conditional.html

и https://www.postgresql.org/docs/9.1/static/sql-createfunction.html

+0

Почему вы читаете инструкцию по совершенно устаревшей версии (7.4) и прекращенная версии (9.1)? –

ответ

2

Вам не нужен запрос, там, как вы передаете все значения функции - просто возвращает значение case:

CREATE OR REPLACE FUNCTION af_calculate_range(tt TEXT, tc INTEGER) 
RETURNS INTEGER IMMUTABLE AS $$ 
BEGIN 
    RETURN CASE tt WHEN 'day' THEN tc * 60 * 60 
        WHEN 'hour' THEN tc * 60 
      END; 
END; 
$$ 
LANGUAGE PLPGSQL; 
+1

Хорошая точка, сам запрос даже не нужен +1. –

2

функция может возвращать только одно значение, так что вы, вероятно, намеревался сделать это:

CREATE OR REPLACE FUNCTION af_calculate_range(tt text, tc integer) RETURNS integer AS $$ 
     SELECT CASE WHEN tt = 'day' THEN tc * 60 * 60 -- return a (single) scalar 
        WHEN tt = 'hour' THEN tc * 60 
       END 
     FROM watchers; 
     $$ 
LANGUAGE SQL; 

Но как отметил @Mureinik, вам даже не нужно делать SELECT; просто используйте выражение CASE.

0

вы более усложняя. Хранить interval в вместо

select now(), now() + interval '2 days'; 
       now    |   ?column?    
-------------------------------+------------------------------- 
2016-12-19 05:23:51.856137-02 | 2016-12-21 05:23:51.856137-02 

create table watchers (
    the_interval interval, 
    timestamp_created timestamp 
); 

insert into watchers (the_interval, timestamp_created) values 
('1 hour', '2016-12-08 15:56:26.169614'); 

Теперь запрос будет:

select * 
from watchers 
where now() > timestamp_created + the_interval 
; 
the_interval |  timestamp_created  
--------------+---------------------------- 
01:00:00  | 2016-12-08 15:56:26.169614 
+0

Я новичок в sql, как он должен выглядеть? – snaggs

+0

@snaggs: Отредактировано –