You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP技术问询:如何查询并显示不在tempahanbilik表中的数据?

修正你的SQL查询逻辑与安全问题

嘿,我看你写的SQL逻辑完全搞反啦,咱们一步步来修正:

原代码的核心问题

  • 表的查询方向错误:你想要的是bilik表中未出现在符合日期条件的tempahanbilik记录里的数据,但原查询是从tempahanbilik表中筛选,这和你的需求完全颠倒了。
  • 子查询逻辑错误:原子查询SELECT bilik.id FROM bilik会取出所有房间ID,tempahanbilik.id NOT IN这个结果的话,相当于找tempahanbilik里不存在于bilik的无效ID,这显然不是你要的。
  • 严重的SQL注入风险:直接把$_SESSION里的变量拼接进SQL语句,恶意用户可以通过构造特殊值篡改你的查询,甚至破坏数据库。

正确的查询写法(两种常用方案)

方案1:使用NOT EXISTS(高效推荐)

这种方式在数据量大时性能更好,逻辑也清晰:

SELECT b.* 
FROM bilik b
WHERE NOT EXISTS (
    -- 检查当前bilik的ID是否在指定日期范围内的tempahanbilik中存在
    SELECT 1 
    FROM tempahanbilik t
    WHERE t.id = b.id 
      AND t.tarikh BETWEEN ? AND ?
)

方案2:使用LEFT JOIN + IS NULL

另一种直观的写法,通过左连接后筛选无匹配的记录:

SELECT b.*
FROM bilik b
LEFT JOIN tempahanbilik t 
  ON b.id = t.id 
  AND t.tarikh BETWEEN ? AND ? -- 把日期条件放在连接条件里
WHERE t.id IS NULL -- 筛选出没有对应tempahanbilik记录的bilik

安全的PHP实现(用预处理语句避免注入)

一定要用mysqli的预处理语句来绑定参数,不要直接拼接变量:

// 准备预处理语句
$query = "SELECT b.* 
          FROM bilik b
          WHERE NOT EXISTS (
              SELECT 1 
              FROM tempahanbilik t
              WHERE t.id = b.id 
                AND t.tarikh BETWEEN ? AND ?
          )";

// 初始化预处理
$stmt = $mysqli->prepare($query);
if (!$stmt) {
    die("预处理失败: " . $mysqli->error);
}

// 绑定参数:'ss'表示两个字符串类型的参数(如果你的tarikh是日期类型,也可以用对应类型)
$stmt->bind_param('ss', $_SESSION['tarikh'], $_SESSION['tarikh2']);

// 执行查询
$stmt->execute();

// 获取结果集
$results = $stmt->get_result();

// 遍历输出数据
while ($row = $results->fetch_assoc()) {
    // 这里处理每条数据,比如echo $row['xxx'];
}

// 清理资源
$stmt->close();

内容的提问来源于stack exchange,提问作者Hasifah Hassan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:21:07