這篇http://boylook.blog.51cto.com/7934327/1325025提到了sql_safe_update的參數及相關結論,下面從源碼上給出比較細節的分析
1.在SQL解析時,如果開啓這個參數,發現謂詞爲空則拋異常:
if ((thd->variables.option_bits & OPTION_SAFE_UPDATES) && !select_lex->where) { my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); DBUG_RETURN(TRUE); }
2.在Delete時:
2.1如果full Join則拋異常
if ((thd->variables.option_bits & OPTION_SAFE_UPDATES) && error_if_full_join(join)) DBUG_RETURN(1);
2.2如果謂詞爲常數則拋異常
if (safe_update && const_cond) { my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); DBUG_RETURN(TRUE); }
2.3如果謂詞無可用索引並且沒有limit拋異常
if (table->quick_keys.is_clear_all()) { thd->server_status|=SERVER_QUERY_NO_INDEX_USED; if (safe_update && !using_limit) { delete select; free_underlaid_joins(thd, select_lex); my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); DBUG_RETURN(TRUE); } }
3.在Update時:
3.1如果full join則拋異常
同上
3.2如果謂詞無可用索引並且沒有limit拋異常
if (table->quick_keys.is_clear_all()) { thd->server_status|=SERVER_QUERY_NO_INDEX_USED; if (safe_update && !using_limit) { my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); goto err; } }
結論:Delete比update有更強的約束,即where條件不能爲空或“永真”