且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

MySQL sql_safe_update简析

更新时间:2022-09-14 14:04:44

1.SQL解析时,如果开启这个参数,发现谓词为空则抛异常:

1
2
3
4
5
6
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则抛异常

1
2
if ((thd->variables.option_bits & OPTION_SAFE_UPDATES) && error_if_full_join(join))
  DBUG_RETURN(1);


2.2如果谓词为常数则抛异常

1
2
3
4
5
6
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抛异常

1
2
3
4
5
6
7
8
9
10
11
12
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抛异常

1
2
3
4
5
6
7
8
9
10
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条件不能为空或“永真”



本文转自MIKE老毕 51CTO博客,原文链接:http://blog.51cto.com/boylook/1328084,如需转载请自行联系原作者