当前位置: 首页
编程语言
ThinkPHP8.0原生SQL查询与执行方法

ThinkPHP8.0原生SQL查询与执行方法

热心网友 时间:2026-06-24
转载

Db::query()只用于SELECT等只读语句,返回二维数组或空数组;Db::execute()用于INSERT等写操作,返回影响行数。二者混用会导致数据未查出或未更新。参数绑定推荐命名占位符。动态字段需白名单校验后拼接。MySQL8 0下需开启PDO模拟预处理。事务中禁止执行DDL语句。

Db::query() 专用于 SELECT 等只读查询语句,返回二维数组;Db::execute() 专用于 INSERT/UPDATE 等写入操作,返回受影响行数。两者语义上严格区分,混用会导致数据无法查出、更新失败或静默无反馈。

ThinkPHP8.0原生SQL执行_ThinkPHP8.0原生SQL查询【数据库】

Db::query()Db::execute() 这两个方法,很多开发者容易混淆的关键点在于——它们并非“随意替换使用”。如果拿 query() 去执行修改数据的 SQL,或者用 execute() 去查询数据列表,结果往往是:数据查不出来、更新未生效、甚至悄无声息地失败。而且,在读写分离的架构下,还会将 SQL 发送到错误的数据库实例上。

查询数据必须用 Db::query(),切勿用它执行 UPDATE

query() 仅处理那些会产生结果集的语句:SELECT、SHOW、EXPLAIN、WITH。它返回的是一个二维数组,即使没有查询到数据,也会返回一个空数组 [],而不是 null。如果执行失败,则返回 false

  • 错误示例:Db::query("UPDATE user SET status = 1 WHERE id = ?", [123]) —— 这种写法不会报错,但检查数据库会发现数据纹丝不动。因为该 SQL 根本没有进入写库流程。
  • 正确示范:Db::query("SELECT * FROM user WHERE status = :status", ['status' => 1])。采用命名占位符绑定参数,可读性和可维护性都显著提升。
  • TP8 也支持问号绑定,但 ? 的先后顺序必须与数组值严格对应,一旦顺序错乱,匹配结果就会出错。因此,推荐优先使用命名绑定(:param)。
  • 调试时,Db::getLastSql() 仅记录最近一次调用。要获取正确的 SQL,必须确保该调用紧跟在 query()execute() 之后。

修改数据必须用 Db::execute(),切勿用它查询列表

execute() 正好相反,它只处理那些没有结果集的写操作:INSERT、UPDATE、DELETE、REPLACE、TRUNCATE。它返回的是受影响的行数(整数),执行失败时同样返回 false

  • 踩坑示例:$list = Db::execute("SELECT * FROM user"); foreach($list as ...) —— 这里 $list 实际上是一个数字,比如 0 或 1。用一个数字去 foreach,程序会直接报错。
  • 正确做法:$affected = Db::execute("UPDATE user SET name = ? WHERE id = ?", [$name, $id]); if ($affected === false) { /* 处理失败 */ }。先判断返回值是否为 false,再决定后续逻辑。
  • 如果需要获取最后一次插入的自增 ID,不能依赖 execute() 的返回值,而应额外调用 Db::getLastInsID()
  • 批量插入数据时,建议使用 Db::name('user')->insertAll($data)。它比手写原生 INSERT 语句更稳定,还能自动处理 SQL 长度超限问题。

动态字段/表名不能绑定,必须经白名单校验后拼接

有一个容易被忽略的细节::table:order_field 这类占位符,在 PDO 预处理器中不会被真正替换。框架会将其视为普通字符串字面量,或者直接导致语法错误。

  • 错误写法:Db::query("SELECT * FROM :table WHERE id = ?", [$tableName, $id])
  • 正确做法:先构建一个白名单数组,例如 ['id', 'name', 'create_time'],然后校验 $sortField 是否在其中。校验通过后,再手动拼接:"ORDER BY {$sortField} DESC"
  • 表前缀可以使用 __USER__ 这种写法,框架会自动替换。但注意,这仅适用于静态写死的场景。如果表名本身是变量,仍需通过白名单校验后手动拼接。
  • 编写 LIKE 模糊查询时,应将通配符包含在绑定值中:['name' => "%{$keyword}%"]。不要将通配符直接写入 SQL 字符串。

MySQL 8.0+ 下原生 SQL 报错?大概率是 PDO 预处理未开启模拟

如果你使用的是 MySQL 8.0 及以上版本,执行原生 SQL 时偶尔会遇到 SQLSTATE[HY000]: General error: 2034 之类的错误。原因在于 TP8 默认未开启 PDO::ATTR_EMULATE_PREPARES => true,而 MySQL 8.0+ 对原生预处理的要求比早期版本更严格。

  • 解决办法很简单:在 config/database.php 文件中,对应的 MySQL 连接配置里,显式添加一行:'options' => [PDO::ATTR_EMULATE_PREPARES => true]
  • 有一个重要的注意事项:DDL 语句(例如 CREATE TEMPORARY TABLE、ALTER TABLE)本身不支持事务回滚。因此,禁止在 Db::startTrans() 事务块中执行这类操作。
  • 事务中的所有原生操作,都必须包裹在 try-catch 中。需要同时捕获 think\db\exception\DataNotFoundException 和底层的 PDO 异常。
  • 即使只执行一个 Db::query(),只要没有抛出异常,框架就会认为“一切正常”,不会自动中断事务。是否回滚,完全取决于你是否在 catch 块中主动 throw 或调用 rollback()

真正容易被忽视的是:事务边界和语句兼容性,从来不是靠框架自动兜底的。一句 SET @var = 1DROP TABLE 写进去,即使外面套了事务,rollback() 也形同虚设。

来源:https://www.php.cn/faq/2680832.html

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
IDEA中SpringBoot项目热部署实现指南

IDEA中SpringBoot项目热部署实现指南

Springboot项目在IDEA中实现热部署需依次完成:开启自动编译(静态与动态编译)、启用热部署策略、引入spring-boot-devtools依赖、关闭浏览器缓存,最后启动测试即可生效,省去手动重启时间,大幅提升开发效率。

时间:2026-07-11 06:47
Java实现Excel转JSON的代码详解

Java实现Excel转JSON的代码详解

使用Java结合FreeSpire XLS库可自动将Excel转为JSON,通过读取工作表并映射为键值对,高效支持数据迁移、报表导出与系统对接,大幅提升效率并消除手动录入错误。

时间:2026-07-11 06:47
Golang高效布谷鸟过滤器多字符集字符串过滤

Golang高效布谷鸟过滤器多字符集字符串过滤

布谷鸟过滤器支持删除操作,通过指纹截断与双哈希定位实现多字符集高效过滤。指纹截断需采用fnv64a或xxhash快速哈希并取低8位,桶索引使用独立双哈希避免假阳性。并发安全需以固定数组配合sync atomic实现。

时间:2026-07-11 06:47
Java使用Poi-tl按Word模板生成动态表格

Java使用Poi-tl按Word模板生成动态表格

Poi-tl是Word导出工具,文档周全,支持多级合并表头生成。通过{{text}}、{{?var}}、{{ table}}标签处理模板,传入TableRenderData对象即可动态渲染表格。示例展示用户信息表格生成,并提供工具类消除表格首行缩进,确保格式正确。

时间:2026-07-11 06:47
Go语言微服务集成Swagger生成交互式API文档完整教程

Go语言微服务集成Swagger生成交互式API文档完整教程

在Go微服务中集成Swagger常见四大问题:swaginit初始化失败需确保存在packagemain及注释;SwaggerUI加载失败因路由映射错误或未导入docs;@Param注解必须严格遵循格式;部署后接口文档显示localhost因硬编码host,应删除或通过环境变量动态注入。

时间:2026-07-11 06:47
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 热门数据榜