2016-09-28 33 views
1

我有幾個插入語句,如果它們是真的,我只想執行。只有在條件爲真時才插入MySQL

這是我的例子:

START TRANSACTION; 

INSERT INTO fields (field_name, control_type_id, needs_approval) 
VALUES 
('Array Photos', 3, 0); 

INSERT INTO field_to_job_type (field_id, job_type_id, sequence_number, parent_id) 
VALUES 
(last_insert_id(), (SELECT job_type_id FROM job_types WHERE job_type_name = 'Cash'), 1, (SELECT field_id FROM fields where field_name = 'Photo Pack')); 

COMMIT; 

現在,我只是真的想如果只有1這個查詢結果運行第二個查詢:

SELECT job_type_id FROM job_types WHERE job_type_name = 'Cash'

如果該查詢返回2個結果,我想放棄該事務。

這可能嗎?我試過的東西:

START TRANSACTION; 
INSERT ...; 
INSERT ...; 
IF(SELECT count(job_type_name) FROM job_types WHERE job_type_name = 'Cash') = 1, 'COMMIT', 'ROLLBACK'); 

其中,顯然沒有工作。

+1

通過放棄交易,你的意思是回滾第一個插入? – RiggsFolly

+0

@FlorianHeer我不認爲這是一個愚蠢的目標 – Drew

+0

選擇計數(*)到一個變種,並做一個「if」塊 – Drew

回答

1

選擇計數到一個變量,然後在比較中使用它。

DECLARE total_row INT DEFAULT 0 

START TRANSACTION; 

INSERT INTO fields (field_name, control_type_id, needs_approval) 
VALUES ('Array Photos', 3, 0); 


SELECT count(job_type_name) FROM job_types WHERE job_type_name = 'Cash' INTO total_rows; 

IF total_rows =2 THEN 
    ROLLBACK; 
ELSE 

    INSERT INTO field_to_job_type (field_id, job_type_id, sequence_number, parent_id) 
    VALUES (last_insert_id(), (SELECT job_type_id FROM job_types WHERE job_type_name = 'Cash'), 1, (SELECT field_id FROM fields where field_name = 'Photo Pack')); 
    COMMIT; 
END IF; 
2

您可以使用WHERE子句此。將您的INSERT VALUES轉換爲INSERT SELECT並添加WHERE子句。

例如,

INSERT INTO fields (field_name, control_type_id, needs_approval) 
SELECT 
'Array Photos', 3, 0 
WHERE Condition; 

如果條件爲真,它會插入該行。如果條件爲假,則SELECT將返回零行,因此INSERT將插入零行。

如果上面的查詢不會因爲語法錯誤運行,你可以像@ spencer7593提到,加FROM DUAL

INSERT INTO fields (field_name, control_type_id, needs_approval) 
SELECT 
'Array Photos', 3, 0 
FROM DUAL 
WHERE Condition; 

DUAL表基本上是一個dummy table that has predictable content and can be relied upon to always have at least one row

+0

我認爲在我們可以添加一個WHERE子句之前,需要在SELECT中有FROM子句。爲此,我們可以使用特殊的DUAL表格,例如'SELECT'Array Photos',3,0 FROM DUAL WHERE ...' – spencer7593

+0

@ spencer7593你試過了嗎?它給你一個語法錯誤? –

+1

**'錯誤代碼1604:...在'WHERE 1 = 1'**附近使用的正確語法** – spencer7593

1

要回答你問,關於有條件地發出ROLLBACK語句的問題:

不能在一個SQL語句的上下文中進行。

我們將需要運行返回結果一個單獨的查詢,檢索結果,然後的if/else使用結果的比較在,並出具單獨的SQL ROLLBACK語句。

我們可以演示如何在MySQL存儲程序中執行這些步驟;但這個問題沒有具體提及使用程序。

或者,相同的步驟可以在一個客戶端程序進行,發出了SELECT查詢單獨的SQL語句,和ROLLBACK。


我會以不同的方式處理設計。如果我們可以提前確定,在我們發出INSERT語句之前,我們想要ROLLBACK事務......那麼我們可以避免首先執行INSERT。並避免不必要的開銷,解析語句,獲取鎖,寫入日誌,生成回滾,浪費AUTO_INCREMENT等。

在MySQL存儲程序(例如PROCEDURE)的上下文中,可以執行SELECT COUNT() INTO var,然後使用IF THEN ELSE塊來測試變量的值。或者,您可以設置一個CONTINUE處理程序來處理特定的異常。

但這個問題沒有具體提到,這是在MySQL存儲程序的上下文中。


就我個人而言,我會以不同的方式處理設計。

我想知道爲什麼這是一個問題,有兩個或更多的行的值爲'Cash'job_type_name

我明白爲什麼它會導致在問題所示的INSERT語句有問題,SELECT查詢返回多行是要拋出一個錯誤,在它的上下文。

但也有修復那。我們可以採取最低或最高價值,使用MIN()MAX()聚合,或者添加ORDER BY ... LIMIT 1,或者我們可以添加一些額外的標準來保證返回單個值。

我想知道job_type_name是否在job_type表中是唯一的。或者我們只關心'Cash'值只出現一次。

看着這個問題,我不禁想知道這是否需要有條件地回滾事務是一個更爲廣泛的設計問題的症狀。

看着被問到的問題,我想這裏還有更多的事情要做。我會後退幾步,重新考慮提議的設計。

相關問題