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

PHP中MySQL子查询报1064语法错误,求高效查询解决方案

解决MySQL语法错误+优化查询逻辑+修复SQL注入风险

咱们一步步拆解你的问题,先搞定语法错误,再优化查询,最后必须提个关乎数据库安全的重要点:

1. 先修正你的MySQL语法错误

你之前尝试的嵌套查询有两处明显的语法问题:

错误语句:SELECT *(events) FROM (SELECT * AS events FROM calendar WHERE event_key LIKE '201974000') AS lineitems

  • *(events) 是无效写法,正确引用子查询字段应该用 events.*
  • 子查询里的 SELECT * AS events 逻辑错误,表别名应该放在子查询括号的后面,不是字段后面

修正后的嵌套查询应该是这样:

SELECT events.* 
FROM (SELECT * FROM calendar WHERE event_key LIKE '201974000%') AS events 
WHERE events.event = 'Event Name'

但其实完全没必要用嵌套子查询,你的需求直接用一条WHERE语句就能实现,更简洁高效:

SELECT * FROM calendar 
WHERE event_key LIKE '{$eventKey}%' 
AND event = '{$eventTitle}'

你之前尝试过类似写法,但少了一个右括号(WHERE (event_key LIKE ... AND event='" . $event . "'),这也是导致报错的原因之一。

2. 重中之重:修复SQL注入漏洞

你现在直接把$eventKey、$eventTitle这类外部变量拼进SQL语句里,存在严重的SQL注入风险——攻击者可以构造恶意值篡改你的数据库操作,甚至删库跑路。必须改用MySQLi的预处理语句来避免这个问题。

比如把查询逻辑改成预处理方式:

// 用?作为占位符代替变量
$sql = "SELECT * FROM calendar WHERE event_key LIKE ? AND event = ?";
// 初始化预处理语句
$stmt = $connection->prepare($sql);
// 给LIKE条件拼接%,绑定参数(s表示字符串类型)
$like_event_key = $eventKey . "%";
$stmt->bind_param("ss", $like_event_key, $eventTitle);
// 执行查询
$stmt->execute();
// 获取查询结果
$result = $stmt->get_result();
// 检查匹配行数
if ($result->num_rows > 0) {
    // 处理已有数据
}
// 关闭语句
$stmt->close();

同样,你的UPDATE和INSERT语句也需要改成预处理写法,比如插入操作:

// 明确指定字段名(避免表结构变化导致插入错误)
$insert = "INSERT INTO calendar (event_num, event, url, image, description, location, start_date, end_date, color)
           VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = $connection->prepare($insert);
// 绑定参数,按字段顺序对应
$stmt->bind_param("sssssssss", $eventNum, $eventTitle, $eventURL, $eventImage, $eventDesc, $eventLocat, $eventStart, $eventEnd, 'FFB819');
$stmt->execute();
$stmt->close();

3. 修正你PHP代码里的小bug

你的seoUrl函数里有一行无效代码:$string = str_replace("");,缺少参数会导致报错,直接删掉这行即可。

另外,建议在INSERT语句中明确指定字段名(如上例),避免表结构调整后插入数据错位。

修正后的核心数据库操作代码

foreach($vcalendar->VEVENT as $event){
    $eventTitle = $event->SUMMARY;
    $eventStart = strtotime($event->DTSTART);
    $eventEnd = strtotime($event->DTEND);
    $eventDesc = $event->DESCRIPTION;
    $eventLocat = $event->LOCATION;
    $eventImage = imageCorrection($event->ATTACH);
    $eventKey = date('YzB',$eventStart);
    $eventURL = seoUrl($eventTitle);

    echo $eventKey."<br>";
    echo $eventTitle."<br>";
    echo $eventURL."<br>";
    echo $eventDesc."<br>";
    echo $eventLocat."<br>";
    echo $eventImage."<br>";
    echo date('m-d-Y h:ia',$eventStart)."<br>";
    echo date('m-d-Y h:ia',$eventEnd)."<br>";

    // 预处理查询事件是否存在
    $sql = "SELECT * FROM calendar WHERE event_key LIKE ? AND event = ?";
    $stmt = $connection->prepare($sql);
    $like_event_key = $eventKey . "%";
    $stmt->bind_param("ss", $like_event_key, $eventTitle);
    $stmt->execute();
    $result = $stmt->get_result();

    echo "Query Results: " . $result->num_rows . " EventKey: " . $eventKey . " " . $eventTitle . "<br>";

    if($result->num_rows > 0){
        echo "Rows: ==" . $result->num_rows . "<br>";
        // 预处理执行更新
        $update = "UPDATE calendar SET url=?, image=?, description=?, location=?, start_date=?, end_date=?, color='FFB819' WHERE event_key LIKE ? AND event=?";
        $update_stmt = $connection->prepare($update);
        $update_stmt->bind_param("ssssssss", $eventURL, $eventImage, $eventDesc, $eventLocat, $eventStart, $eventEnd, $like_event_key, $eventTitle);
        $update_stmt->execute();
        $update_stmt->close();
    }else{
        echo "Rows: #" . $result->num_rows . "<br>";
        // 预处理查询同eventKey前缀的记录数
        $key_sql = "SELECT * FROM calendar WHERE event_key LIKE ?";
        $key_stmt = $connection->prepare($key_sql);
        $key_stmt->bind_param("s", $like_event_key);
        $key_stmt->execute();
        $key_result = $key_stmt->get_result();
        $eventNum = $key_result->num_rows;
        $eventNum++;
        echo "Query 2 Rows: ##" . $eventNum . "<br>";
        $key_stmt->close();

        // 格式化eventNum
        if($eventNum < 10){
            $eventNum = "00" . $eventNum;
        }elseif($eventNum < 100){
            $eventNum = "0" . $eventNum;
        }
        $eventNum = $eventKey . $eventNum;
        echo "Event#: " . $eventNum . "<br>";

        // 预处理执行插入
        $insert = "INSERT INTO calendar (event_num, event, url, image, description, location, start_date, end_date, color)
                   VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
        $insert_stmt = $connection->prepare($insert);
        $insert_stmt->bind_param("sssssssss", $eventNum, $eventTitle, $eventURL, $eventImage, $eventDesc, $eventLocat, $eventStart, $eventEnd, 'FFB819');
        $insert_stmt->execute();
        $insert_stmt->close();
    }
    $stmt->close();
    echo "==============================================================================<br>";
}

最后小提示

测试用的echo语句上线前记得注释或删除,避免泄露敏感数据;另外确保你的数据库用户权限最小化,只给必要的增删改查权限。

内容的提问来源于stack exchange,提问作者PrismaPixel Studios

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:37:35