根据行是否存在更新/插入

时间:2012-07-19 11:00:35

标签: php sql postgresql

处理一些postgreSQL查询。正如我在上一个问题中所说的那样..我对SQL逻辑的了解非常有限......

我有这个插入行的查询。

$timestamp = date('Y-m-d G:i:s.u');
$check_time = "start"; //can also be stop
$check_type = "start_user"; //can also be stop_user

$insert_query = "INSERT INTO production_order_process_log (
production_order_id, 
production_order_process_id, 
$check_time, 
$check_type) 
    VALUES (
'$production_order_id', 
'$production_order_process_id', 
'$timestamp', 
'$user')
";

不幸的是,每次都会添加一个新行。我想添加条件SQL以便

如果production_order_process_id不存在,请执行上面查询中写入的INSERT。也就是说,添加包含所有新信息的新行

但如果production_order_process_id确实存在且check_typestop_user,则更新该行以使用stop填充列$timestamp并填写列stop_user$user

我明白这很复杂..或者,至少对我来说这是^^非常感谢你的帮助!

5 个答案:

答案 0 :(得分:2)

这通常称为MERGE或upsert。 PostgreSQL没有明确支持此操作。

我在PostgreSQL中看到MERGE主题的最佳文章是this one by depesz

答案 1 :(得分:1)

如果您可以创建存储过程并在插入新记录时调用,那将是件好事。

    DELIMITER $$

    DROP PROCEDURE IF EXISTS `DB`.`InsertNewRow` $$
    CREATE PROCEDURE `db`.`InsertNewRow` ()
    BEGIN

    DECLARE V_EXIST INT DEFAULT 0;
    DECLARE   V_check_type VARCHAR(20);


    SELECT production_order_process_id,check_type INTO V_EXIST,V_check_type FROM production_order_process_log;

    IF V_EXIST=0 THEN

      INSERT INTO production_order_process_log (
      production_order_id,
      production_order_process_id,
      $check_time,
      $check_type)
        VALUES (
      '$production_order_id',
      '$production_order_process_id',
      '$timestamp',
      '$user');

    ELSEIF V_check_type='stop_user' THEN


      /* UPDATE QUERY HERE */

    END IF;
    END $$

    DELIMITER ;         

答案 2 :(得分:1)

插入类型ON DUPLICATE KEY UPDATE ...

答案 3 :(得分:1)

使用MERGE声明

以下是用法

MERGE INTO table [[AS] alias]
USING [table-ref | query]
ON join-condition
[WHEN MATCHED [AND condition] THEN MergeUpdate | DELETE]
[WHEN NOT MATCHED [AND condition] THEN MergeInsert]

MergeUpdate is
UPDATE SET { column = { expression | DEFAULT } |
          ( column [, ...] ) = ( { expression | DEFAULT } [, ...] ) }
[, ...]
(yes, there is no WHERE clause here)

MergeInsert is
INSERT [ ( column [, ...] ) ]
    { DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, ...] )
[, ...]}
(no subquery allowed)

如果您搜索它,我相信您会找到更多文章/示例。

答案 4 :(得分:0)

只需在插入内容中添加WHERE CLAUSE:

INSERT INTO production_order_process_log   
           (  production_order_id, production_order_process_id, check_time, check_type)
    VALUES ( '$production_order_id', '$production_order_process_id', '$timestamp', '$user')
WHERE NOT EXISTS ( SELECT *
        FROM production_order_process_log nx
        --
        --  assuming production_order_id is the Primary Key, here
        --
        WHERE nx.production_order_id = '$production_order_id'
        );

更新:我对参数和VALUE()感到困惑。下面的片段没有参数,但是 使用立即值:

INSERT INTO tmp.production_order_process_log
           (  production_order_id, production_order_process_id, check_time, check_type)
    SELECT 1, 2, '2012-07-19 12:12:12', 'Lutser'
WHERE NOT EXISTS ( SELECT *
        FROM tmp.production_order_process_log nx
        --
        --  assuming production_order_id is the Primary Key, here
        --
        WHERE nx.production_order_id = 1
        );

(您必须稍微更改一下才能重新添加参数)