本地localhost环境报MariaDB 1064 SQL语法错误(GETDATE()附近)求助
问题基本情况
- 故障仅在本地localhost环境复现
- 数据库返回错误编号1064:SQL语法错误,错误位置为第1行
'GETDATE())'附近 - 报错文件路径:
C:/xampp/htdocs/daftarpasien/system/database/DB_driver.php,报错行号691 - 触发错误的SQL语句:
SELECT MAX(RIGHT(DaftarNomor,2)) AS kd_max FROM TDaftarTelepon_Coba WHERE DaftarTanggal= CONVERT(date,GETDATE())
- 关联业务代码:
$date= date("Y-m-d"); $kodeunit = $this->input->post('UnitKode'); $q = $this->db->query("SELECT MAX(RIGHT(DaftarNomor,2)) AS kd_max FROM TDaftarTelepon_Coba WHERE DaftarTanggal= CONVERT(date,GETDATE())"); $kd = ""; if ($q->num_rows() > 0) { foreach ($q->result() as $k) { $tmp = ((int)$k->kd_max) + 1; $kd = sprintf("%02s", $tmp); } } else { $kd = "01"; }
错误产生原因
- 核心原因是数据库函数语法不兼容:
GETDATE()是SQL Server专属的获取当前日期时间的内置函数,本地XAMPP环境默认搭载的是MariaDB数据库,不存在该函数,SQL解析到该位置时直接抛出1064语法错误,这也是问题仅在本地环境出现的核心原因——如果线上环境使用SQL Server则可以正常识别该语法,本地MariaDB无法识别。 - 次要原因为
CONVERT函数写法不匹配:MariaDB/MySQL中CONVERT函数的参数顺序为CONVERT(待转换值, 目标类型),和SQL Server的CONVERT(目标类型, 待转换值)参数顺序完全相反,即使替换GETDATE()为MariaDB支持的日期函数,原写法依然会触发语法错误。 - 代码冗余问题:业务逻辑中已经通过PHP的
date("Y-m-d")提前获取了格式匹配的当前日期值,但SQL语句中未使用该变量,硬编码了依赖特定数据库的函数写法,额外引入了兼容风险。
修复方案
方案1:适配本地MariaDB环境修改SQL语法
将SQL中SQL Server专属的日期写法替换为MariaDB原生支持的写法,CURDATE()是MariaDB/MySQL内置的获取当前日期的函数,返回值格式为YYYY-MM-DD,和DaftarTanggal字段格式完全匹配,无需额外做类型转换。
修改后的业务代码:
$date= date("Y-m-d"); $kodeunit = $this->input->post('UnitKode'); // 替换为MariaDB兼容的日期查询逻辑 $q = $this->db->query("SELECT MAX(RIGHT(DaftarNomor,2)) AS kd_max FROM TDaftarTelepon_Coba WHERE DaftarTanggal= CURDATE()"); $kd = ""; if ($q->num_rows() > 0) { foreach ($q->result() as $k) { $tmp = ((int)$k->kd_max) + 1; $kd = sprintf("%02s", $tmp); } } else { $kd = "01"; }
方案2:跨环境兼容写法(推荐)
直接使用代码中已经提前计算好的PHP日期变量,通过参数绑定的方式传入SQL查询,完全不依赖数据库端的专属内置函数,不管后端对接SQL Server还是MariaDB都可以正常运行,同时参数绑定的写法也能避免SQL注入风险。
修改后的业务代码:
$date= date("Y-m-d"); $kodeunit = $this->input->post('UnitKode'); // 绑定PHP端计算好的日期参数,屏蔽数据库语法差异 $q = $this->db->query("SELECT MAX(RIGHT(DaftarNomor,2)) AS kd_max FROM TDaftarTelepon_Coba WHERE DaftarTanggal= ?", array($date)); $kd = ""; if ($q->num_rows() > 0) { foreach ($q->result() as $k) { $tmp = ((int)$k->kd_max) + 1; $kd = sprintf("%02s", $tmp); } } else { $kd = "01"; }
内容的提问来源于stack exchange,提问作者yehuda satrio
相关产品推荐
相关产品推荐

