2012-12-13 46 views
0

我正在使用嚴格模式開啓的MySQL。我通過HTML表單插入用戶提供的數據。我已經完成了所有的驗證,這是最後一步。我可以安全地認爲這個INSERT成功了嗎?

這是從我的PHP代碼的摘錄:

$sql = 'SET sql_mode = TRADITIONAL'; //last chance data validation 
$mysqli->query($sql) or output_error('Database Error: Failed to set SQL mode'); 

$db_err_msg = 'Database Error: Failed to update profile summary'; 
$sql = "INSERT INTO {$tables['text']} (lngProfileId, memProfileText) VALUES(?, ?) 
    ON DUPLICATE KEY UPDATE memProfileText = VALUES(memProfileText)"; 
$stmt = $mysqli->prepare($sql) or output_error($db_err_msg); 
$stmt->bind_param('is', $profile_id, $_POST['memProfileText']) 
    or output_error($db_err_msg); 
$stmt->execute() or output_error($db_err_msg); 
$stmt->close(); 

//if code reaches this point, can it assume insert/update succeeded? 

注:output_error是致命錯誤,我的錯誤處理程序。它不會返回;它退出。

我需要檢查警告嗎?或者我可以安全地假設插入/更新成功?是否有一些情況可能導致警告而不是錯誤,即使嚴格模式打開?

編輯:我只關心應該考慮的事情致命錯誤。如果它被更新而不是插入,這是我不關心的。這不是一個錯誤。

另外,在這種情況下,last_insert_idaffected_rows是沒有意義的。如果用戶沒有進行任何更改,affected_rows將爲0,last_insert_id的值將不會更新。

我的定義在這種情況下成功

  • 它插入記錄或更新記錄或做過什麼,如果未進行任何更改
  • 它並沒有「悄悄裂傷我的數據」

許多新手程序員犯的錯誤假設查詢成功,沒有檢查返回值或警告。他們的代碼在正常情況下工作 ...。

我的問題是:??「考慮到我的代碼,以嚴格的方式開啓,錯誤檢查我所做的,是安全的假設查詢成功那是一個正確或不正確的假設我應該還要檢查警告還是會是多餘的?「

+0

你測試了嗎?如果它起作用,它就會起作用。 –

+0

是的,我測試過了。它適用於我投擲的所有東西。但我想確保沒有一些我不考慮的場景。我試圖確保我編寫健壯的代碼。 – toxalot

+0

不要解決不存在的問題。你不想重新測試mysql,php驅動程序的功能。或者你也可以寫自己的驅動程序,DB –

回答

0

雖然我認爲這可能是一個安全的假設,但我認爲比對不起更安全。我已經在close語句之前的execute語句之後直接添加了以下代碼。

//I think this is probably redundant, but just in case 
if ($mysqli->warning_count) { 
    $warnings = $stmt->get_warnings(); 
    do { 
     trigger_error('Database Warning (' . $warnings->errno . '): ' 
      . $warnings->message, E_USER_WARNING); 
    } while ($warnings->next()); 
} 

我已經添加了評論,以便我記得我爲什麼要這樣做。

0

是的,你可以安全地假設,但只是爲了雙重檢查獲取插入的最新記錄的ID。如果有一個ID,它被插入然後

+0

在這種情況下,最後一個插入的id不會告訴我很多。請參閱編輯我的問題。 – toxalot

1

您應該檢查mysqli::info()函數的值。

如果插入數據字符串會是這個樣子,

Records: 1 Duplicates: 0 Warnings: 0 

另一個功能是mysqli::affected_rows。它返回最後一次插入/更新/刪除查詢所影響的行數。

+0

'mysqli :: $ info()'只適用於某些語句。對於單個插入,它將返回一個空字符串。如果該行已經存在並且未被更改,mysqli :: $ affected_rows'將返回0。我的問題是詢問*我是否需要檢查警告*而不是如何獲取這些信息。 – toxalot

相關問題