2012-07-19 58 views
2

處理一些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然後更新該行與$timestamp填補列stop,並填寫列stop_user$user

我知道這很複雜..或者,至少對我來說是^^非常感謝您的幫助!

+0

標準SQL將是'MERGE'。但我不認爲Postgre支持它?嘗試http://stackoverflow.com/questions/1109061/insert-on-duplicate-update-postgresql – podiluska 2012-07-19 11:03:26

+0

@podiluska很快谷歌讓我覺得也許不是那麼好:(有沒有其他的方式?我會研究一個postgresql' MERGE'或替代更多.. – 1252748 2012-07-19 11:05:56

+0

重複的問題:http://stackoverflow.com/questions/1109061/insert-on-duplicate-update-postgresql – 2012-07-19 11:12:32

回答

2

這通常被稱爲MERGE或UPSERT 。 PostgreSQL沒有明確的支持這個操作。

我見過的關於PostgreSQL中MERGE主題的文章是this one by depesz

+0

爲什麼合併比使用條件邏輯來測試字段是否爲NULL更好?謝謝! – 1252748 2012-07-19 21:00:47

+0

因此,如果'start'i是'NULL',我把'$ timestamp'放入它中,但是如果它有一個值,我把它放到'stop'中。 – 1252748 2012-07-19 21:04:00

+0

@thomas併發性,基本上。考慮一下你正在檢查的記錄會發生什麼樣的變化。如果要避免這種情況,可以使用'SELECT ... FOR UPDATE',如果你非常小心,但它在任何情況下都不起作用。 – 2012-07-20 02:04:18

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

不幸的是,存儲過程將不得不等待,直到我可以將此數據庫遷移到我的mySQL或msSQL就像我的服務器技術試圖在本週早些時候安裝postgresql PDO包導致了一些非常嚴重的問題,我知道它們包含在mySQL的PHP​​中。雖然postgre已經爲我工作了很長一段時間,但我不能等到我使用mySQL! – 1252748 2012-07-19 11:08:46

1

插入式對重複密鑰更新後...

+0

是的,但不要忘記給你想用作鍵索引或唯一索引的列 – Sliq 2012-07-19 11:09:27

+1

不支持Postgres – 2012-07-19 11:11:43

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) 

我敢肯定,你會發現更多的文章/如果你搜索它的例子。

+2

不支持Postgres – 2012-07-19 11:11:27

0

只是廣告中的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' 
     ); 

更新:我是由參數和值混淆()。下面的代碼片段工作沒有參數,但 與立即值:

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

(你必須改變它有點重新添加參數)

+0

我很抱歉,但是這只是對我有點幫助頭。 production_order_id是生產訂單的主鍵。什麼是NX?對不起,如果真的基本困惑><.. – 1252748 2012-07-19 11:11:23

+0

nx是子查詢的*相關名*(又名別名)。子查詢測試行是否存在(對於production_order_id = 1)並返回True或False。是的:這是非常基本的。並且:這個語法*由* postgres支持。 (我測試過了!) – wildplasser 2012-07-19 11:21:42

+0

是啊^^漂亮的初學者.. :)謝謝你的幫助! – 1252748 2012-07-19 11:28:06

相關問題