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


UPDATE/INSERT based on if a row exists

处理一些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确实存在并且stop_user check_type,则更新该行以用$timestamp填充列stop,并用$user填充列stop_user

我知道这很复杂。或者,至少对我来说是^^ 非常感谢您的帮助!

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

我见过的关于PostgreSQL中MERGE主题的最好的文章是depesz的这篇文章。

插入后键入 在重复键更新时...

使用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)

我相信如果你搜索它,你会发现更多的文章/例子。

如果可以创建一个存储过程并在插入新记录时调用,那就太好了。

    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 ;         

只需在插入处添加一个 WHERE 子句:

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
        );

(您必须对其进行一些更改才能重新添加参数(