Mysql中varchar字元串的比較,swoole預處理參數綁定

  • 2019 年 12 月 15 日
  • 筆記

寫在前面

事情起因:

使用了一個varchar類型的欄位儲存數字值。

在根據該欄位進行大小篩選的時候,出現該問題。

類似select * from sheets where s_status > 3

分析

php調用時條件傳的是數字類型

組件生成的SQL語句直接執行正常

排查

打開了mysql的運行日誌,分析到最終運行的sql語句大概如下

where s_status > '3'

使用的是php swoole,預處理。

解決有兩條路

  • mysql的欄位類型改為數字
  • 研究swoole的參數預處理問題,可以測試普通PHP的預處理是否也有問題

能學習的點

  • 字元串類型欄位的比較規則

mysql中字元串類型欄位的比較規則

找了一圈資料,相關文章比較少,終於在比較不起眼的角落裡找到資料。

字元串比較 是根據ascii碼比較 只有當第一個字元相同才對比第二個字元。以此類推。 在線轉換ascii碼工具 https://www.iamwawa.cn/ascii.html

假設我們現在表中有2條欄位

id

s_status

s_name

1

4

測試1

2

258710588

測試2

如果按正常的sql執行 我篩選>3應該是2條結果都有,但是程式運行只能得到1條結果: id = 1的數據

那麼我們上面說到 字元串的比較規則,從第一個字元開始比較,只有第一個字元相等 才會比較第二個字元…

『4』 > 『3』 通過

字元 4 對應的ASCII碼為 52  字元 3 對應的ASCII碼為 51

『258710588』 > 『3』 不通過

字元 2 對應的ASCII碼為 50  字元 3 對應的ASCII碼為 51  此時已經有結果 不需要對比第二個字元

如果是』31』 > 『3』 也會通過

第一個字元相同,則對比第二個字元,而3沒有第二個字元了 所以是小於。

研究:php預處理時,參數綁定

// 省去連接等等  // 預處理及綁定  $stmt = $conn->prepare("SELECT * FROM `siam_test_bug` WHERE `s_wechat_cross_status` > ? ");    $condition = 3;  $stmt->bind_param("i", $condition); // 生成語句 > 3  $stmt->bind_param("s", $condition); // 生成語句 > '3'  就變成了字元串比較 不正常    $res    = $stmt->execute();  $result = $stmt->get_result();    while ($myrow = $result->fetch_assoc()) {      var_dump($myrow);      echo "<br/>";  }

確定swoole

經過開發組內各位大哥的協助確定,是swoole的參數綁定,不支援決定類型,所以會出現這個坑。

已經提交swoole rfc 待解決