我试图在psql上创建一个函数。它将在桌面上插入时触发。我想在我的选择上注入一个变量。无法工作......
CREATE OR REPLACE FUNCTION updateHistoricLongTime()
RETURNS void AS $$
DECLARE
hour_nb int;
index_hour int;
saved_hours int;
tmp_counter int;
BEGIN
hour_nb := 0;
index_hour := 1;
saved_hours := 2160;
tmp_counter := 0;
SELECT COUNT(*) FROM locationhistoric WHERE type='hour' AND idLocation=6 INTO hour_nb;
IF (hour_nb<saved_hours) THEN
FOR i IN 1 .. saved_hours LOOP
SELECT COUNT(*) FROM visits
WHERE stend < (timestamp '2017-11-29 15:00' - interval **>> index_hour<<<** - 1 ' hour') AND stend > (timestamp '017-11-29 15:00' - interval **>>index_hour <<<**' hour') AND location_id=6 AND duration>0 INTO tmp_counter;
index_hour := index_hour + 1;
END LOOP;
END IF;
END;
$$
LANGUAGE 'plpgsql' IMMUTABLE;
如何在SELECT COUNT(*)FROM Visits ...
中注入变量index_hour编辑:这只是语法问题,但我无法找到正确的方法!
命令行中的结果:
ERROR: syntax error at or near "index_hour"
LINE 16: ... stend < (timestamp '2017-11-29 15:00' - interval index_hour...
非常感谢, 解决方案
CREATE OR REPLACE FUNCTION updateHistoricLongTime()
RETURNS void AS $$
DECLARE
hour_nb int;
index_hour int;
saved_hours int;
tmp_counter int;
index_hour_minor int;
BEGIN
hour_nb := 0;
index_hour := 1;
index_hour_minor := 0;
saved_hours := 2160;
SELECT COUNT(*)
INTO hour_nb
FROM locationhistoric
WHERE type='hour'
AND idLocation=6;
IF (hour_nb<saved_hours) THEN
FOR i IN 1 .. saved_hours LOOP
SELECT COUNT(*)
INTO tmp_counter
FROM visits
WHERE start > timestamp '2017-11-29 15:00' - ( interval '1 hour' * index_hour )
AND start < timestamp '2017-11-29 15:00' - ( interval '1 hour' * index_hour_minor)
AND location_id=6
AND duration>0;
INSERT INTO locationhistoric
(type, date, counter, idLocation)
VALUES( 'hour',
timestamp '2017-11-29 15:00' - ( interval '1 hour' * index_hour_minor),
tmp_counter,
6);
index_hour_minor := index_hour_minor + 1;
index_hour := index_hour + 1;
END LOOP;
END IF;
END;
$$
LANGUAGE plpgsql;
答案 0 :(得分:2)
为间隔指定的值不能作为变量传递。但是,如果基本单位总是一小时,你可以将我们的间隔乘以我们想要的数字,例如
interval '1' hour * 5
将返回5小时。 5
可以是参数。所以你的查询应该是:
SELECT COUNT(*)
INTO tmp_counter
FROM visits
WHERE stend < (timestamp '2017-11-29 15:00' - (interval '1' hour * index_hour))
AND stend > (timestamp '2017-11-29 15:00' - (interval '1' hour * index_hour))
AND location_id=6
AND duration > 0;
答案 1 :(得分:1)
您希望获得查询的语法(例如,index_hour = 8):
select count(*)
from visits
where
stend < (timestamp '2017-11-29 15:00' - interval '7 hour') and
stend > (timestamp '2017-11-29 15:00' - interval '8 hour') and
location_id = 6 and
duration > 0;
注意引号所在的位置。这意味着您的变量必须在pl / pgsql中的引号内,这意味着它将被视为文字。
解决方案是:
execute
'select count(*) ' ||
'from visits ' ||
'where ' ||
'stend < (timestamp ''2017-11-29 15:00'' - interval ''' || (index_hour - 1) || ' hour'') and ' ||
'stend > (timestamp ''2017-11-29 15:00'' - interval ''' || index_hour || ' hour'') and ' ||
'location_id = 6 and ' ||
'duration > 0'
为了节省我设置数据,我使用我拥有的表(驱动程序)编写了一个更简单的示例,以便我可以测试。请注意,您必须使用2个单引号将一个引号引入字符串,这意味着要仔细计算引号。
create function a47768241() returns integer
as $body$
declare
index_hour int;
id integer;
begin
index_hour = 8;
execute
'select id ' ||
'from driver ' ||
'where ' ||
'from_date_time < (timestamp ''2013-04-22 16:00:00'' - interval ''' || (index_hour - 1) || ' hour'') '
into id;
return id;
end;
$body$
language 'plpgsql';
简单测试:
# select a47768241();
a47768241
-----------
158
(1 row)
使用结果值检查日期:
# select * from driver where id = a47768241();
id | vehicle_id | person_id | from_date_time | to_date_time | created_at | updated_at
-----+------------+-----------+---------------------------+---------------------------+----------------------------+------------
158 | 6784 | 15430 | 2012-09-13 17:00:41.39778 | 2012-09-14 01:54:46.39778 | 2016-06-03 16:43:11.456063 |
(1 row)
答案 2 :(得分:0)
只是连接间隔值,如
interval concat(index_hour - 1 , ' hour')