MySQL sql_safe_update簡析

這篇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條件不能爲空或“永真”



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章