男的舔女的下面视频在线播放-少妇愉情理仑片高潮日本-久久久久久国产一区二区三区-麻豆精品一区二区综合-国产精品超碰在线观看-网红极品女神精品视频在线-国产亚洲综合777-高清性视频一区二区播放-中文字幕第一页亚洲天堂

返回列表 發(fā)帖
查看: 610|回復(fù): 3

[求助] 使用原生DELET語句無空格時(shí)無法刪除數(shù)據(jù)的問題

1

主題

6

回帖

1

粉絲

初學(xué)乍練

貢獻(xiàn)
0 點(diǎn)
金幣
10 個(gè)
樓主
發(fā)表于 2026-1-16 10:43:04 |北京| 只看樓主 |倒序?yàn)g覽 |閱讀模式

1. 問題:

我使用DELETE語句刪除數(shù)據(jù)的時(shí)候,如果引號(hào)內(nèi)兩側(cè)不留空的時(shí)候,刪除就不會(huì)執(zhí)行,比如,下面這樣就可以成功從數(shù)據(jù)庫中刪除: delpsqlf="DELETEFROMdatatable WHERE sid = sid";DB::query(delpsqlf); 而下面這樣,顯示已執(zhí)行,但數(shù)據(jù)庫中的數(shù)據(jù)并未刪除,數(shù)據(jù)庫也無報(bào)錯(cuò): delpsqlf="DELETEFROMdatatable WHERE sid = sid";DB::query(delpsqlf);

2. 千問的回答:

針對(duì)上述問題,我將discuz_database.php發(fā)給千問,給的結(jié)果為:
通過分析您提供的PHP類代碼,我發(fā)現(xiàn)問題出在Discuz框架的SQL安全檢查機(jī)制上。讓我為您詳細(xì)解釋:
問題根源
問題主要出現(xiàn)在discuz_database_safecheck::checkquery()方法中,這個(gè)方法負(fù)責(zé)SQL語句的安全檢查。關(guān)鍵代碼如下:
$cmd = strtoupper(substr(trim($sql), 0, 3)); if(isset(self::$checkcmd[$cmd])) { $check = self::_do_query_safe($sql); }
這里self::$checkcmd定義為:
protected static $checkcmd = array('SEL'=>1, 'UPD'=>1, 'INS'=>1, 'REP'=>1, 'DEL'=>1);
具體分析
當(dāng)SQL語句有前后空格時(shí)(" DELETE FROM table WHERE sid = sid"trim(sql)會(huì)移除前后空格,得到"DELETE FROM table WHERE sid = sid"substr(trim(sql), 0, 3)返回"DEL" "DEL"在checkcmd數(shù)當(dāng)SQL時(shí)"DELETEFROMtableWHEREsid=sid"): 同樣經(jīng)過trim()處理,理論上應(yīng)該得到相同結(jié)果 但在_do_query_safe()方法中,正則清理邏輯對(duì)格式高度敏感:
$clean = preg_replace("/[^a-z0-9_\-\(\)#\*\/\"]+/is", "", strtolower($clean));
這個(gè)復(fù)雜的清理邏輯可能因缺少空格而導(dǎo)致清理后的SQL字符串不包含"del"關(guān)鍵字 最終安全檢查失敗,但框架沒有拋出異常,而是靜默失敗

3. 智普的回答:

針對(duì)上述問題,我將discuz_database.php發(fā)給千問,給的結(jié)果為:
這個(gè)問題出在 DB::query 方法中提取 SQL 命令類型的邏輯上。
問題分析
當(dāng)你在 SQL 語句字符串($delpsqlf)的開頭(引號(hào)內(nèi)側(cè))添加空格時(shí),DB::query 中的代碼邏輯會(huì)導(dǎo)致返回值類型不一致,從而影響你的業(yè)務(wù)邏輯判斷(例如 if(DB::query(...)))。 請(qǐng)看 discuz_database 類中的 query 方法:
public static function query($sql, $arg = array(), $silent = false, $unbuffered = false) { // ... 前面的代碼省略 ... // 執(zhí)行 SQL 查詢 $ret = self::$db->query($sql, $silent, $unbuffered); if (!$unbuffered && $ret) { // 【問題出在這里】 // 使用 strpos 查找第一個(gè)空格的位置來截取命令名稱(如 DELETE, SELECT 等) $cmd = trim(strtoupper(substr($sql, 0, strpos($sql, ' ')))); if ($cmd === 'SELECT') { // ... } elseif ($cmd === 'UPDATE' || $cmd === 'DELETE') { // 如果命令是 UPDATE 或 DELETE,將返回值替換為受影響的行數(shù) $ret = self::$db->affected_rows(); } elseif ($cmd === 'INSERT') { $ret = self::$db->insert_id(); } } return $ret; }
為什么會(huì)有兩種結(jié)果?
情況一:語句前面有空格(" DELETE FROM ...") strpos(sql,′′)會(huì)個(gè)0substr(sql, 0, 0) 返回空字符串 ""。 cmdcmd 不等于 'DELETE',代碼跳過了 ret=self::db->affected_rows(); 這一步。 最終 DB::query 返回的是 MySQL 的結(jié)果對(duì)象(Resource/Object)。 在 PHP 中,非空的對(duì)象轉(zhuǎn)換為布爾值通常是 true。所以你的代碼認(rèn)為“執(zhí)行成功”。
情況二:語句前面沒有空格("DELETE FROM ...") strpos(sql,′′)會(huì)DELETE6substr(sql, 0, 6) 返回 "DELETE"。 cmd"DELETE"進(jìn)elseif(cmd === 'UPDATE' || cmd===DELETE)ret 被賦值為 self::$db->affected_rows()(受影響的行數(shù))。 關(guān)鍵點(diǎn): 如果 SQL 實(shí)際上沒有刪除任何數(shù)據(jù)(例如 sid 不匹配,或者你使用了事務(wù)未提交),affected_rows() 返回 0。 你的代碼判斷 if(0) 結(jié)果為 false,所以你認(rèn)為“執(zhí)行失敗”或“未刪除”。
為什么數(shù)據(jù)庫里實(shí)際上沒被刪除?
既然情況一顯示“成功刪除”,情況二顯示“未刪除”,但你提到情況二“數(shù)據(jù)庫中的數(shù)據(jù)并未刪除”,這意味著 affected_rows 確實(shí)返回了 0。 這說明在兩種情況下,發(fā)給數(shù)據(jù)庫的 SQL 語句實(shí)際上可能都沒有匹配到數(shù)據(jù)(或者 $sid 在第二種情況下的值有問題)。但是:
javascript
我知道答案 回答被采納將會(huì)獲得1 貢獻(xiàn) 已有3人回答
回復(fù)

使用道具 舉報(bào)

46

主題

3336

回帖

10

粉絲

應(yīng)用開發(fā)者

Discuz! 運(yùn)維

貢獻(xiàn)
225 點(diǎn)
金幣
685 個(gè)
QQ
沙發(fā)
發(fā)表于 2026-1-16 11:03:06 |江蘇| 只看Ta
;P代碼都貼不好,這AI開發(fā)者真的是。。。
回復(fù)

使用道具 舉報(bào)

15

主題

3686

回帖

5

粉絲

應(yīng)用開發(fā)者

貢獻(xiàn)
438 點(diǎn)
金幣
172 個(gè)
QQ
板凳
發(fā)表于 2026-1-16 11:30:53 |河南| 只看Ta
科站網(wǎng) 發(fā)表于 2026-1-16 11:03
;P代碼都貼不好,這AI開發(fā)者真的是。。。

拒絕為 ai開發(fā)者 提供任何幫助
回復(fù)

使用道具 舉報(bào)

5

主題

20

回帖

2

粉絲

初學(xué)乍練

貢獻(xiàn)
0 點(diǎn)
金幣
8 個(gè)
地板
發(fā)表于 2026-1-16 11:41:07 |河南| 只看Ta
你問gemini啊,國(guó)內(nèi)的不行

3. 如何驗(yàn)證和修復(fù)?

為了徹底解決這個(gè)問題,建議按以下步驟操作:

第一步:確認(rèn)數(shù)據(jù)庫里的真實(shí)數(shù)據(jù)

不要只用肉眼看,使用 SQL 的長(zhǎng)度函數(shù)來檢查數(shù)據(jù)庫里到底存了什么。
執(zhí)行這個(gè)查詢(假設(shè)你要查 sid 為 '1001' 的那條):
SQL-- MySQL / PostgreSQL / SQLite SELECT sid, LENGTH(sid) as len FROM datatable WHERE sid LIKE '%1001%';
  • 如果顯示 sid1001,但 len6(而不是4),說明前后各有一個(gè)空格。
  • 這就是為什么你不留空格刪不掉,留了空格(剛好湊對(duì)了)才能刪掉的原因。

第二步:修復(fù)代碼(推薦使用 TRIM)

為了防止未來再出現(xiàn)這種“必須手動(dòng)加空格才能刪”的玄學(xué)問題,建議在 SQL 中忽略空格,或者在代碼層清理數(shù)據(jù)。
方案 A:在 SQL 中強(qiáng)制忽略兩端空格(最穩(wěn)妥) 無論數(shù)據(jù)庫里有沒有空格,都進(jìn)行修剪后再比對(duì):
SQL-- 將數(shù)據(jù)庫里的字段和傳入的值都去除空格進(jìn)行比對(duì) DELETE FROM datatable WHERE TRIM(sid) = TRIM('你的變量值');
方案 B:在插入數(shù)據(jù)時(shí)就清洗 這是治本的方法。在寫入數(shù)據(jù)庫(INSERT/UPDATE)之前,確保對(duì)變量進(jìn)行了 trim() 處理(去除首尾空格)。

第三步:使用參數(shù)化查詢(Binding)

你目前使用的看起來像是字符串拼接(String Concatenation),這不僅容易出現(xiàn)空格拼接錯(cuò)誤,還極易遭受 SQL 注入攻擊
建議改為參數(shù)化查詢(偽代碼示例):
C++// 錯(cuò)誤寫法(拼接) query("DELETE FROM table WHERE sid = '" + sid + "'"); // 正確寫法(參數(shù)化綁定) // 這樣你就不用擔(dān)心引號(hào)、空格拼接的問題,數(shù)據(jù)庫庫函數(shù)會(huì)幫你處理 query.prepare("DELETE FROM table WHERE sid = ?"); query.bindValue(0, sid.trimmed()); // 傳入前去除空格 query.exec();

總結(jié)

你遇到的“不報(bào)錯(cuò)但不刪除”,是因?yàn)?*WHERE 條件沒有匹配到任何數(shù)據(jù)**。最直接的原因是你的數(shù)據(jù)庫中存儲(chǔ)的數(shù)據(jù)包含了首尾空格,導(dǎo)致精確匹配失敗。
下一步建議: 你可以先執(zhí)行一句 SELECT sid FROM datatable WHERE sid LIKE '%...%' 看看那些刪不掉的數(shù)據(jù)長(zhǎng)度是多少,確認(rèn)是否包含空格。需要我?guī)湍銓戓槍?duì)你特定數(shù)據(jù)庫類型的排查 SQL 嗎?
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

  • 關(guān)注公眾號(hào)
  • 有償服務(wù)微信
  • 有償服務(wù)QQ

手機(jī)版|小黑屋|Discuz! 官方交流社區(qū) ( 皖I(lǐng)CP備16010102號(hào) |皖公網(wǎng)安備34010302002376號(hào) )|網(wǎng)站地圖|star

GMT+8, 2026-4-18 02:35 , Processed in 0.059258 second(s), 12 queries , Redis On.

Powered by Discuz! X5.0 Licensed

© 2001-2026 Discuz! Team.

關(guān)燈 在本版發(fā)帖
有償服務(wù)QQ
有償服務(wù)微信
返回頂部
快速回復(fù) 返回頂部 返回列表