详细介绍:SQL 执行异常排查 java.sql.SQLException:从 SQLException 说起

news/2025/10/1 10:32:41/文章来源:https://www.cnblogs.com/slgkaifa/p/19122205

详细介绍:SQL 执行异常排查 java.sql.SQLException:从 SQLException 说起

网罗开发(小红书、快手、视频号同名)

  大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。

图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

展菲:您的前沿技术领航员
大家好,我是展菲!
全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
公众号“Swift社区”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
微信端添加好友“fzhanfei”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!


文章目录

    • 前言
    • 场景描述:常见的 SQLException 问题
    • 排查思路:怎么快速锁定问题?
    • Demo:带日志的 SQL 执行封装
    • 结合实际开发的应用
    • 总结

前言

在日常开发中,大家应该或多或少都遇到过这种情况:SQL 在本地跑得好好的,一放到服务里执行就报 java.sql.SQLException。很多同学看到这个异常时,第一反应就是“是不是数据库挂了?”。其实绝大多数情况跟数据库无关,而是 SQL 拼接、参数绑定或者日志缺失导致的。

这篇文章我结合一个小 Demo,带大家看一下 SQLException 的常见原因,以及如何一步步排查。

场景描述:常见的 SQLException 问题

假设我们有一张 users 表,结构很简单:

CREATE TABLE users (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
age INT
);

在 Java 项目里写了一个最普通的查询:

String sql = "SELECT * FROM users WHERE username = ? AND age = ?";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1, "zhangfei");
ps.setInt(2, 18);
ResultSet rs = ps.executeQuery();

看似没问题,但在真实项目里,很容易因为下面几个问题报 SQLException

  1. SQL 拼接错误:比如忘了 AND,或者参数占位符数量不对。
  2. 参数绑定异常:明明是数字,结果 setString();或者顺序错了。
  3. SQL 没有打印日志:导致无法复现真实执行的 SQL。

排查思路:怎么快速锁定问题?

遇到 SQLException 时,不要慌,通常从以下几个角度来排查:

  1. 打印完整 SQL
    很多时候,你以为你执行的是 SELECT * FROM users WHERE username = 'zhangfei',实际上可能变成了 SELECT * FROM users WHERE username = 'null'

  2. 检查参数绑定
    确认每个 ? 是否都被正确赋值,并且类型匹配。

  3. 用日志记录 SQL
    不仅要打印原始 SQL,还要把 参数替换后的 SQL 打出来,方便直接拿去数据库执行。

Demo:带日志的 SQL 执行封装

我们可以写一个简单的工具方法来封装 SQL 执行和日志打印。这样每次执行 SQL 时,都能清晰看到完整的 SQL。

import java.sql.*;
import java.util.Arrays;
public class JdbcHelper {
public static void executeQuery(Connection conn, String sql, Object... params) {
try (PreparedStatement ps = conn.prepareStatement(sql)) {
// 参数绑定
for (int i = 0; i < params.length; i++) {
ps.setObject(i + 1, params[i]);
}
// 打印完整 SQL
System.out.println("Executing SQL: " + buildFullSql(sql, params));
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
System.out.println("User: " + rs.getString("username") + ", Age: " + rs.getInt("age"));
}
}
} catch (SQLException e) {
System.err.println("SQL 执行异常: " + e.getMessage());
e.printStackTrace();
}
}
// 将参数替换到 SQL 中(简易版)
private static String buildFullSql(String sql, Object... params) {
String fullSql = sql;
for (Object param : params) {
String value = (param instanceof String) ? "'" + param + "'" : String.valueOf(param);
fullSql = fullSql.replaceFirst("\\?", value);
}
return fullSql;
}
// Demo 入口
public static void main(String[] args) throws Exception {
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/testdb", "root", "password");
executeQuery(conn, "SELECT * FROM users WHERE username = ? AND age = ?", "zhangfei", 18);
}
}

运行效果:

Executing SQL: SELECT * FROM users WHERE username = 'zhangfei' AND age = 18
User: zhangfei, Age: 18

一旦 SQL 写错,比如参数缺失,就能立刻在日志里看到:

Executing SQL: SELECT * FROM users WHERE username = 'zhangfei' AND age = null
SQL 执行异常: Unknown column 'null' in 'where clause'

是不是就一目了然了?

结合实际开发的应用

在真实的业务开发中,SQLException 的定位通常会踩到几个坑:

  • 多服务场景:调用链太长,不知道 SQL 是在哪个微服务里执行的。
  • ORM 框架二次封装:比如 MyBatis,把 SQL 隐藏在 XML 里,导致排查困难。
  • 日志打印不全:只打印了原始 SQL,没有参数,运维无法复现。

因此,建议大家在项目里加一个 SQL 拦截器,不论是 MyBatis 的 Interceptor,还是 JPA 的日志配置,都要确保能拿到 完整 SQL

总结

java.sql.SQLException 本质上不是“数据库坏了”,而是代码逻辑和 SQL 执行之间的沟通问题。核心思路就是:

  1. 先把完整 SQL 打印出来
  2. 确认参数绑定是否正确
  3. 保证日志可复现

这样基本上 90% 的 SQL 问题都能快速解决。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/923751.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

做个外贸网站一般需要多少钱高校思政课网站建设

引言 在安卓开发中&#xff0c;视图绑定是一个关键的步骤&#xff0c;它允许开发者将布局文件中的视图组件与Activity或Fragment中的成员变量关联起来。这一机制不仅使得UI操作更加便捷&#xff0c;而且提高了开发效率。本文主要探讨了安卓开发中的一项重要技术——View Bindin…

2025上海寿衣哪里买权威推荐:优质供货商与暖心服务之选

上海寿衣厂家权威推荐:优质供货商与暖心服务之选 在中国传统文化中,寿衣作为人生最后一程的重要服饰,承载着对逝者的尊重与缅怀。随着社会对殡葬文化重视程度的提升,寿衣行业也逐步走向规范化、专业化发展。上海作…

AI 真能胜任专业工程师的工作吗?

AI 真能胜任专业工程师的工作吗? 近年来,人工智能(AI)的发展速度令人目不暇接,能够完成写诗、绘画、考试,甚至编写复杂的计算机代码。然而,有一个疑问始终在用户的心头环绕,得不到答案:这位“学霸”走出考场,…

容器中与内存相关的几个参数

在容器环境中,Cache内存使用率通常指的是容器内存中被操作系统用于缓存文件系统数据的部分。操作系统会利用未使用的内存来缓存磁盘上的数据,以提高文件读写性能。这部分内存虽然被标记为“已使用”,但实际上可以在…

求购做网站阿里巴巴上做网站

双线性插值公式 对于一个目的像素&#xff0c;设置坐标通过反向变换得到的浮点坐标为(iu,jv) (其中i、j均为浮点坐标的整数部分&#xff0c;u、v为浮点坐标的小数部分&#xff0c;是取值[0,1)区间的浮点数)&#xff0c;则这个像素得值 f(iu,jv) 可由原图像中坐标为 (i,j)、(i1…

深入解析:【黑马程序员】后端Web基础--Maven基础和基础知识

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

一个网站如何做双语在国内做敏感网站

腾讯云幻兽帕鲁服务器4核16G、8核32G和16核64G配置可选&#xff0c;4核16G14M带宽66元一个月、277元3个月&#xff0c;8核32G22M配置115元1个月、345元3个月&#xff0c;16核64G35M配置580元年1个月、1740元3个月、6960元一年&#xff0c;腾讯云百科txybk.com分享腾讯云幻兽帕鲁…

php 简单下载数据库数据 导出cvs - 何苦

php 简单下载数据库数据 导出cvs<?php set_time_limit(0);// 下载文件名 $filename = date(Y-m-d H:i:s, time()); //输出Excel文件头,可把user.csv换成你要的文件名 header(Content-Type: application/vnd.ms-ex…

新乡营销型网站建设浦东高端网站开发

1. Homography 单应性概念 考虑 同一个平面(比如书皮)的两张图片&#xff0c;红点表示同一个物理坐标点在两张图片上的各自位置。在 CV 术语中&#xff0c;我们称之为对应点。 Homography 就是将一张图像上的点映射到另一张图像上对应点的3x3变换矩阵. 因为 Homography 是一个 …

上海城市建设官方网站如何用html做班级网站

转载&#xff1a;https://www.cnblogs.com/lnlvinso/p/8848883.html 结果&#xff1a;skiplist的高度是个随机值。 SkipList理解 记下自己对跳表SkipList的理解。 SkipList采用空间换时间的思想&#xff0c;通过增加数据间的链接&#xff0c;达到加快查找速度的目的。 数据库L…

网站与网址的区别制作平台网站方案

应用(Docker)使用WAF接入internet&#xff0c;nginx log 查不到用户的真实IP地址&#xff0c;于是修改nginx 设置&#xff0c;以下都是在linux下操作&#xff1a; 由于没有WAF权限&#xff0c;所以在 docker上启动了两个container&#xff0c;一个模拟WAF(r-proxy)&#xff0c…

OpenWRT中备份多个docker容器的脚本 -

在OpenWrt 24.10.1上测试通过 #!/bin/sh # OpenWrt Docker Container Backup Script # Backup docker container and copy to network storageecho "==========================================" echo &quo…

网站常用的优化方法有哪些做网站的策划需要做什么

1 二叉树的概念 二叉树是&#xff1a; 空树非空&#xff1a;根节点&#xff0c;根节点的左子树、根节点的右子树组成的。 二叉树定义是递归式的&#xff0c;因此后序基本操作中基本都是按照该概念实现的。 2 二叉树的遍历 2.1 前序、中序以及后序遍历 学习二叉树结构&#xf…

动态分区分配算法

首次适应算法[first fit] 每次都从低地址开始查找,找到对歌能满足大小的空闲分区 空闲分区以地址递增的次序排列,每次分配内存时顺序查找空闲分区链或表,找到大小能满足要求的第一个空闲分区 最佳适应算法[best fit…

上海殡葬一条龙服务权威推荐:寿衣、骨灰盒购买定制服务暖心陪伴与专业仪式之选

在生命的最后旅程中,一份专业、周到且充满人文关怀的殡葬服务,不仅是对逝者的尊重,更是对生者的慰藉。随着社会需求的不断提升,上海殡葬服务行业逐步走向规范化、专业化和人性化,各类服务机构不断优化服务流程,提…

百度建设自己的网站wordpress博客访问

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

potplayer截图

Potplayer播放器截图的方法: 在视频区域右击,选择“视频” -> “图像截取” -> “截存当前实画面”(快捷键:Ctrl+Alt+E)。

OpenAI发布提示词集

OpenAI发布提示词集OpenAI 发布“Prompt Packs”300+ 精选提示 Prompt12 个大类(IT、人力资源、销售、产品、客户服务……)每个角色 25 根据 KPI 和产品背景调整以获得最佳结果!https://academy.openai.com/public/…

做的网站需要什么技术支持中山网站建设文化咨询

jedis是一个著名的key-value存储系统&#xff0c;而作为其官方推荐的java版客户端jedis也非常强大和稳定&#xff0c;支持事务、管道及有jedis自身实现的分布式。在这里对jedis关于事务、管道和分布式的调用方式做一个简单的介绍和对比&#xff1a;一、普通同步方式最简单和基础…

网站不备案能解析吗福州市做网站公司

之前有一个公司案例&#xff0c;是这样的&#xff1a; 公司名称&#xff1a;智慧科技有限公司 背景&#xff1a; 智慧科技有限公司是一家拥有数百名员工的中型企业&#xff0c;随着业务的快速发展&#xff0c;公司面临着网络管理上的挑战。 员工在日常工作中需要频繁地访问…