PostgreSQL - 使用ELSIF语句创建函数时出现语法错误

时间:2014-09-08 18:45:59

标签: sql postgresql plpgsql

有人可以帮助解释以下代码的语法错误:

CREATE OR REPLACE FUNCTION linearly_decrement_offset(location_in text)
RETURNS void AS
$BODY$BEGIN

IF tempoffset.ts_insert <= (now() at time zone 'utc') - '15 minutes':: interval AND tempoffset.ts_insert > (now() at time zone 'utc') - '30 minutes':: interval THEN
    UPDATE tempoffset
        SET offset_factor = offset_factor * 0.75
        WHERE tempoffset.location = location_in;
ELSIF tempoffset.ts_insert =< (now() at time zone 'utc') - '30 minutes'::interval AND tempoffset.ts_insert > (now() at time zone 'utc') - '45 minutes'::interval THEN
    UPDATE tempoffset
        SET offset_factor = offset_factor* 0.5
        WHERE tempoffset.location = location_in;
ELSIF tempoffset.ts_insert =< (now() at time zone 'utc') - '45 minutes'::interval AND tempoffset.ts_inset > (now() at time zone 'utc') - '1 hour'::interval THEN
    UPDATE tempoffset
        SET offset_factor = offset_factor * 0.25
        WHERE tempoffset.location = location_in;
ELSIF tempoffset.ts_insert < (now() at time zone 'utc') - '1 hour'::interval THEN
    DELETE FROM tempoffset;
END IF;

END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION linearly_decrement_offset(text)
OWNER TO postgres;

尝试执行时出现以下错误。

ERROR:  syntax error at or near "IF"
LINE 3:  IF tempoffset.ts_insert <= (now() at time zone 'utc') - '15...
         ^
********** Error **********

ERROR: syntax error at or near "IF"
SQL state: 42601
Character: 9

3 个答案:

答案 0 :(得分:2)

您无法在if语句中使用类似的表列。您需要首先使用select .. into检索行的值并将其存储在局部变量中。然后你可以比较这些值。

类似的东西:

CREATE OR REPLACE FUNCTION linearly_decrement_offset(location_in text)
RETURNS void AS
$BODY$
declare
   l_insert_ts timestamp;  --- a local variable to hold the value
BEGIN

   -- this select assumes that location_in is unique 
   -- (and thus the select returns exactly one row)
   -- otherwise the select .. into will throw an error
   select ts_insert
      into l_insert_ts
   from tempoffset
   WHERE location = location_in;

    IF l_insert_ts <= (now() at time zone 'utc') - '15 minutes'::interval AND l_insert_ts > (now() at time zone 'utc') - '30 minutes'::interval THEN
        UPDATE tempoffset
            SET offset_factor = offset_factor * 0.75
            WHERE tempoffset.location = location_in;
    ELSIF l_insert_ts <= (now() at time zone 'utc') - '30 minutes'::interval AND l_insert_ts > (now() at time zone 'utc') - '45 minutes'::interval THEN
        UPDATE tempoffset
            SET offset_factor = offset_factor* 0.5
            WHERE tempoffset.location = location_in;
    ELSIF l_insert_ts <= (now() at time zone 'utc') - '45 minutes'::interval AND l_insert_ts > (now() at time zone 'utc') - '1 hour'::interval THEN
        UPDATE tempoffset
            SET offset_factor = offset_factor * 0.25
            WHERE tempoffset.location = location_in;
    ELSIF tempoffset.ts_insert < (now() at time zone 'utc') - '1 hour'::interval THEN
        DELETE FROM tempoffset;
    END IF;

END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

答案 1 :(得分:1)

这是你想要应用于整个表tempoffset的东西吗?我可能遗漏了一些东西,但是,正如a_horse_with_no_name所说,你可以通过更新然后删除来执行此操作,例如:

$BODY$
BEGIN

update tempoffset
set offset_factor = offset_factor *
   when tempoffset.ts_insert >= (now() at time zone 'utc') - '15 minutes'::interval
    AND tempoffset.ts_insert < (now() at time zone 'utc') - '30 minutes'::interval) then 0.75
   when tempoffset.ts_insert >= (now() at time zone 'utc') - '30 minutes'::interval
    AND tempoffset.ts_insert < (now() at time zone 'utc') - '45 minutes'::interval) then 0.50
   when tempoffset.ts_insert >= (now() at time zone 'utc') - '45 minutes'::interval
    AND tempoffset.ts_insert < (now() at time zone 'utc') - '60 minutes'::interval) then 0.25;

delete from tempoffset where tempoffset.ts_insert < (now() at time zone 'utc') - '15 minutes'::interval or
            tempoffset.ts_insert > (now() at time zone 'utc') - '60 minutes'::interval);


END;
$BODY$

对不起,我没有测试过,我之前没有用过when / then。但是,这将根据适当的因素更新tempoffset表,或者如果时间没有括起来,则数据将被删除。我感觉像&lt; =&gt;向后包围,但是,也许我错了。

-g

答案 2 :(得分:0)

尝试删除if语句中'15分钟':: interval之间的空格。