0

I'm using postgresql and I want to insert or update records with a function in my program. But the thing I have to know is, if a record with conditions I look for is already in database, I will update it, else I will insert a new record. With details:

Table :

CREATE TABLE running_check
(
  "UID" character varying(100) NOT NULL,
  "CameraIP" character varying(100),
  "ErrorStatus" integer,
  "IsRunning" boolean,
  "CheckTime" timestamp without time zone
);

Some example records:

UID        CameraIP         ErrorStatus        IsRunnning     CheckTime
------------------------------------------------------------------
12E        10.0.0.26        0                  true           now()
C26        10.0.0.22        0                  true           now()
454        10.0.0.13        3                  false          now()

I need a function like:

InsertRunningCheckInfo(character varying, character varying, integer, boolean )

And when I call the function, firstly I need to check the records in table if a record with the same UID already exist, then if its "IsRunning" value is true, just update the "CheckTime", else update its ErrorStatus, IsRunning and CheckTime values, if a record with the same UID doesn't exist, insert a new record.

Actually, the problem I face is about not knowing how to use a Select query in a function to check its fields then do work, because I'm too new to Postgresql, searched for it for a while but couldn't find something useful for me. Maybe another way is available for this task in Postgresql that I don't know, so wanted to ask you.

Thanks in advance.

4

3 回答 3

3

存储过程的主体中,您可以执行以下操作:

SELECT UID
FROM running_check
WHERE UID = myparameter;

IF FOUND THEN
  -- UPDATE running_check SET ... WHERE UID = myparameter
ELSE
  -- INSERT INTO running_CHECK ...
END IF;

found布尔值检查前一条语句的结果。我不再有可用的 Postgres 环境,所以我无法检查。但这应该将您推向正确的方向。

于 2013-05-16T08:54:29.187 回答
1

您可以将更新和插入与数据修改公用表表达式组合成一条语句,其中 CTE 尝试更新表,如果更新未返回任何行(即如果它没有找到要更新的行)。

代码将类似于:

with
  cte_update_attempt as (
    update t
    set    col2 = 'f'
    where  col1 = 1
    returning *)
insert into t (
  col1,
  col2)
select
  1,
 'f'
where
  not exists (
    select null
    from   cte_update_attempt);

http://sqlfiddle.com/#!12/7d846/2

于 2013-05-17T11:32:27.887 回答
-1

好或坏,我对我的问题的解决方案:

CREATE OR REPLACE FUNCTION insertrunningcheckinfo(character varying, character varying, integer, boolean) RETURNS void
    LANGUAGE plpgsql
    AS $_$

        DECLARE 
    record_number INTEGER;

BEGIN
 --LOOP

    Select Into record_number "RecordNo" from "running_check" where "UID" = $1 order by "RecordNo" DESC limit  1 ;

    UPDATE "running_check"
    SET   "CheckTime" = now()
        WHERE "RecordNo" = record_number and ("IsRunning" = true and $4 = true);

        IF found THEN
            RETURN;
        END IF;


        UPDATE "running_check"
    SET   "CheckTime" = now()
        WHERE "RecordNo" = record_number and ("IsRunning" = false and $4 = false) and "Status" = $3;

        IF found THEN
            RETURN;
        END IF;

--BEGIN --BEGIN INSERT

    INSERT INTO "running_check"(
            "UID", 
            "CameraIP", 
            "Status",
            "IsRunning",
            "CheckTime")

    VALUES ($1, 
        $2, 
        $3,
        $4,
        now()
        );

    RETURN;
    EXCEPTION WHEN unique_violation THEN
    -- Do nothing
--END; --END INSERT
--END LOOP;
END;
$_$;
于 2013-05-17T11:13:55.517 回答