简体   繁体   English

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

[英]UPDATE/INSERT based on if a row exists

Working on some postgreSQL queries. 处理一些postgreSQL查询。 As I said in a previous question..my knowledge of SQL logic is quite limited.. 正如我在上一个问题中所说的那样。.我对SQL逻辑的了解非常有限。

I have this query that inserts a row. 我有此查询插入一行。

$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')
";

Unfortunately, that is adding a new row every time. 不幸的是,这每次都会添加一个新行。 I would like to add conditional SQL so that 我想添加条件SQL,以便

if the production_order_process_id doesn't exist, do the INSERT as it's written in the query above. 如果production_order_process_id不存在,请按照上面查询中的说明进行INSERT。 That is, add the new row with all the new information 也就是说,用所有新信息添加新行

but if the production_order_process_id does exist and the check_type is stop_user then UPDATE the row to fill the column stop with the $timestamp and fill the column stop_user with $user . 但是,如果production_order_process_id确实存在并且check_typestop_user则更新该行以用$timestamp填充stop列, stop_user$user填充stop_user列。

I understand this is complicated.. Or, at least for me it is ^^ Thanks much for the help! 我知道这很复杂。或者,至少对我来说,是^^非常感谢您的帮助!

This is usually called MERGE or upsert. 这通常称为MERGE或upsert。 PostgreSQL doesn't have explicit support for this operation. PostgreSQL没有对此操作的明确支持。

The best article I've seen on the topic of MERGE in PostgreSQL is this one by depesz . 我在PostgreSQL上关于MERGE的主题上看到的最好的文章是depesz撰写的这篇文章

It would be good if you can create a stored procedure and call while insert new record. 如果您可以创建一个存储过程并在插入新记录的同时进行调用,那将是很好的。

    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 ;         

插入后,键入ON DUPLICATE KEY UPDATE ...

Use MERGE statement 使用MERGE语句

Here is the usage 这是用法

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)

I'm sure you'll find more articles/examples if you search for it. 我敢肯定,如果您搜索它,将会找到更多的文章/示例。

Just ad a WHERE CLAUSE to the insert: 只需在插入处添加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'
        );

UPDATE: I was confused by the parameters and the VALUE() . 更新:我对参数和VALUE()感到困惑。 The fragment below works without parameters, but with immediate values: 下面的片段可以不带参数,但具有立即值:

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

(you'll have to change it a bit to re-add the parameters) (您必须对其进行一些更改以重新添加参数)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM