2016-08-27 10 views
1

クエリを作成したい "このsensor_idのレコードが存在する場合は、その値を持つレコード、sensor_idと時間 "を返します。PostgreSQLの "IF EXISTS" - レコードが存在する場合にレコードを更新するクエリを作成していない場合に挿入します。

私はこのクエリを作成するために管理:

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

データ型は?私は 'CREATE TABLE measurement_pm2_5(measurement_timeタイムスタンプNOT NULL、sensor_id整数NOT NULL DEFAULT 1、measurement_value整数NOT NULL DEFAULT 1)OIDSなし 'でテストしました。期待通りに動作します。 –

+0

私の質問が更新されました。 – Defozo

+0

なぜ行が更新されなかったと思いますか?クエリをテストするためにどのようなクライアントソフトウェアを使用していますか? 'do'文は有用な情報そのものを返しません(エラーが発生した場合を除く)。 'update'文を' UPDATE public.measurement_pm2_5 SET measurement_value = measurement_value + 0.01 ... 'に変更するだけで、すべてのOK(またはそうでないこと)を確認できます。 – Abelisto

答えて

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; 
+0

あなたの答えをありがとう。クエリは私よりもはるかに明確に見えますが、それでも機能しません。私は何か間違っていることは明らかですが、私は何が分かりません。私の質問では2番目のクエリである 'SELECT'はレコードを返しますが、指定されたクエリは0行に影響します。 – Defozo

+0

心配しないでください:) – Defozo

関連する問題