我想进行查询"如果该秒内的记录和此sensor_id存在,请使用提供的新值更新它,否则使用该值创建记录,sensor_id和时间"。
我设法创建了这个查询:
DO
$do$
BEGIN
IF EXISTS (
SELECT
1
FROM
public.measurement_pm2_5
WHERE
measurement_time >= TO_TIMESTAMP('06.07.2016 23:28:43', 'DD.MM.YYYY HH24:MI:SS')
AND measurement_time < TO_TIMESTAMP('06.07.2016 23:28:44', 'DD.MM.YYYY HH24:MI:SS')
AND sensor_id = 2
) THEN UPDATE
public.measurement_pm2_5
SET
measurement_value = 27
WHERE
measurement_time >= TO_TIMESTAMP('06.07.2016 23:28:43', 'DD.MM.YYYY HH24:MI:SS')
AND measurement_time < TO_TIMESTAMP('06.07.2016 23:28:44', 'DD.MM.YYYY HH24:MI:SS')
AND sensor_id = 2;
ELSE INSERT
INTO
public.measurement_pm2_5
( sensor_id, measurement_time, measurement_value )
VALUES
( 2, TO_TIMESTAMP('06.07.2016 23:28:43', 'DD.MM.YYYY HH24:MI:SS'), 27 );
END IF;
END;
$do$
LANGUAGE plpgsql;
但它没有按预期工作。
Query OK, 0 rows affected (execution time: 62 ms; total time: 62 ms)
虽然这个查询:
SELECT
1
FROM
public.measurement_pm2_5
WHERE
measurement_time >= TO_TIMESTAMP('06.07.2016 23:28:43', 'DD.MM.YYYY HH24:MI:SS')
AND measurement_time < TO_TIMESTAMP('06.07.2016 23:28:44', 'DD.MM.YYYY HH24:MI:SS')
AND sensor_id = 2
返回一条记录,第一个查询的UPDATE
部分看起来不会被执行。
我正在使用PostgreSQL 9.5。
我做错了什么?
编辑:
measurement_pm2_5表:
CREATE TABLE public.measurement_pm2_5 (
sensor_id SERIAL,
measurement_time TIMESTAMP WITHOUT TIME ZONE NOT NULL,
measurement_value NUMERIC(6,2) NOT NULL,
CONSTRAINT measurement_pm2_5_sensor_id_fkey FOREIGN KEY (sensor_id)
REFERENCES public.sensor(id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
NOT DEFERRABLE
)
WITH (oids = false);
答案 0 :(得分:1)
从您的SQL代码中可以很容易地看出您在过程编程语言方面经验丰富。 PL / pgSQL需要不同的思维方式。仔细阅读the docs on PL/pgSQL programming并开始思考成功或失败的集合和操作。这根本不是要贬低你;把它看作是一个看过两边的同事的程序员的意见。
在这种情况下,只需尝试UPDATE
,如果失败,请改为INSERT
。
DO $do$
DECLARE
obs timestamp := to_timestamp('06.07.2016 23:28:43', 'DD.MM.YYYY HH24:MI:SS');
BEGIN
UPDATE public.measurement_pm2_5
SET measurement_value = 27
WHERE measurement_time = date_trunc('second', obs)
AND sensor_id = 2;
IF NOT FOUND THEN
INSERT INTO public.measurement_pm2_5
(sensor_id, measurement_time, measurement_value)
VALUES (2, obs, 27);
END IF;
END;
$do$ LANGUAGE plpgsql;