MYSQL Error 2 Query double

A key point

    MYSQL queries double error arises, there are two key points:

  Generates temporary tables (1) SQL statement using the GROUP BY statement;

  (2) RAND () is generated and stored in the query may be different random numbers.

Added: ================================================ =========================================== 
(. 1) Group
by Chang and min (), max (), COUNT (), SUM (), AVG () like aggregate function in conjunction with, such as: SELECT name , COUNT ( * ) from user Group by name; this statement based on user table name packet fields, the same values will be recorded in the name field is divided into the same group, and COUNT ( * ) will be calculated in each group,
the number of records, when we run the above statements will be: + --- -----
+ - ---------- + | name | COUNT ( * ) | + -------- + - ---------- + | andy | 1 | | nana | 1 | | Mike | 1 | + -------- + - + ---------- name field in the user table has three values: mike, anna, andy, so that the SQL statement will be executed after the three packets, the number of records of each packet is 1; us to the user
add a record in the table:
INSERT INTO User value ( . 4 , ' Mike ' ); this time table has two people with the same name, Mike call, then when the SQL statement is executed, the result will be as follows: + ---- + ---- - ---------- + | name |  COUNT ( *) | + -------- + - ---------- +
   
   
    | Andy  |          . 1 |
    | Nana |          . 1 |
    | mike |          2 |
    + -------- + - ---------- +
packet field value name mike, it is possible to see 2 becomes the number of records.

(2) RAND () function to generate random numbers (except for 0 and 1) between 0 and 1
==================== ================================================== ==========================

 

Second, the principle explore

  1. Review the error messages generated SQL statement using the built environment in the "MYSQL double Query Error 1":

SELECT  COUNT ( * ), the concat (( SELECT  Database ()), Floor ( RAND () * 2 )) AS A from  User  Group  by A; 

Description: SQL statement, rand () * 2 randomly generated between 0 and 2 (not including 0 and 2) the random number, and the floor (rand () * 2) is randomly produce one of the two numbers 0 and 1 

  When the code executes, during a session, the database maintains a session for the current master key is a temporary table, each field is as follows:

a    COUNT ( * ) 

Additional information: In fact, the order of the fields should count (*) a primary key we just put on a front

     For each of a value generated by our SQL statement, the database will first query the temporary table has not the same as a field value, and if so, the appropriate count (*) character

  Segment value by 1, otherwise it will be a value into a temporary table in a field, the corresponding count (*) field value is set to 1. Here, we first and patted two questions:

   (1) value for a newly created, temporary tables have inquiring whether the same error occurs when a field value?

   (2) the value for a newly created, temporary table is not inquiring whether the same error occurs when a field value?

  First to solve the first problem the SQL statement is modified as follows:

SELECT  COUNT ( * ), the concat (( SELECT  Database ()), . 1 ) AS A from  user  Group  by A; 

changes: for each record in the user table, a is the value of the SQL statements are generated injection1

     Repeatedly implementation of the new SQL statement is: there is no query error occurs, the results of each have been as follows:

   

   Why not produce a query mistake? During this period, understanding how information is stored in a temporary table changes will understand. First of all, the beginning of the temporary table has no data.

   

   For the first record in the user table, a new SQL statement generated a value injection1, database query in a temporary table to a field does not have any value and just produce

   A same value, decided: the a value into a field .

                                            

   For the second record user table, a value of the new SQL statements generated for the same injection1, database query in a temporary table to have a new field values ​​and

   As the a value decided: the corresponding count (*) field value incremented by one .

                                            

   user table has four records, count the final temporary table (*) field will change to 4. It can be seen during a session of the new SQL statement is executed, no query error occurred.

   情况逐渐明了了,查询错误的产生可能与第一个问题无关. 接下来我们讨论第二个问题.

   

   2. 为了便于叙述,将新的SQL语句称为SQL2,而另一个称为SQL1吧.  执行SQL1,当产生的a值与临时表中的各个a字段值不

   同时(查询阶段),会将新的a值插入临时表中的a字段(插入阶段),并将对应的count(*)字段值置为1. 过程中,错误

   就发生在插入阶段. 在这个过程中,有两个关键的时点,一是查询二时插入,在这两个时间点,rand()都会产生随机数,

   随机数的产生使得两个时间点的a值有可能不一致,导致在插入阶段可能发生错误. 简单点说就是:在查询阶段和插入阶段的a

   值有可能不同,这就是造成错误的原因. 接下来,我们从1条记录开始慢慢增加user表中的记录数,每一次都执行SQL1,看看

   会发生什么.

   (1)记录数为1时(只保留id为1的记录)

   

   情况是:无论执行多少次,都不会发生错误,为什么呢?首先临时表是空的,而user表中只有一条记录,对应

   要统计到临时表中的a值也只有一个,错误自然不会发生.

   (2)记录数为2时(增加id为2,name为anna的记录)

   

   可以看到,第三次执行SQL1的时候,发生了错误. 第一次为什么没错误呢?发生的情况是这样的.

     i)针对user表中的第一条记录,产生的a值为injection0,查询阶段的a值就是injection0,查询到临时表中a字段值没

   有injection0,于是数据库决定:插入a值. 前面我们说过,由于随机数的关系,在插入阶段a值有可能会变化,有可能变为

   injection1,或者还是injection0.不过这时候由于临时表是空的,所以都不会有错误发生,在插入阶段a为injection0时,就

   插入injection0,否则插入injection1.显然,这里最终插入的是injection0. 

     ii)针对user表中第二条记录,产生的a值必然是injection0,在查询阶段数据库检查到临时表中a字段值中有injection0,

   于是数据库决定:将对应的count(*)字段值加1. 这时候,不论在插入阶段a值变为什么,数据库都不会再执行检查,而是直

   接将count(*)字段值加1. 这就是第一次执行SQL1时发生的情况. 那么对于第一次执行SQL1,在什么情况下会发生错误呢?

     iii)在ii中,针对user表中第二条记录产生的a值若为injection1,在查询阶段数据库检查到临时表中所有a字段值中没有

   injection1,于是决定:将injection1插入到临时表中. 不巧,在插入阶段,a值变为了injection0,由于表中本来就存在

   injection0了,于是就会报错了. 同样可以这样去分析第二次第三次执行SQL1发生的情况.

   (3)记录数为3及以上,都会引发错误.

 

   3. 经过以上分析,我们已经抓到了错误最关键的点了:在查询阶段和插入阶段的主键值不一致导致了错误的产生.

 

三、结论

  在将数据统计到临时表中时(查询阶段和插入阶段的数据不一致),由于主键具有唯一性,如果某主键值在临时表中已经存

  在,而在插入阶段还试图插入相同的主键值时,数据库便会报错.

 

====================================== 参考 ========================================

https://www.cnblogs.com/laoxiajiadeyun/p/10278512.html

   

 

  

Guess you like

Origin www.cnblogs.com/soldierback/p/11314039.html