Java/JDBC:执行任意 SQL 语句(DML、DDL)时获得有意义的结果

问题描述 投票:0回答:1

是否有一种可靠的方法来获取 SQL 语句的类型(SELECT、INSERT、UPDATE、DELETE,如果可能的话,还有 CREATE、TRUNCATE、DROP、ALTER...),而无需进行广泛解析? DB 是否返回所执行语句类型的可靠指示符,最好是可以从

java.sql.PreparedStatement
中扣除的指示符?

详细说明这个问题:一个简单的方法是检查第一个关键字,但这似乎很容易出错(例如以

WITH
开头的状态、PL/SQL 语法、专有关键字等)。在没有外部资源的情况下纯粹用 Java 真正确定类型的想法似乎令人畏惧,特别是在考虑各种数据库供应商和版本(包括未来版本)时。

据我所知,执行任意语句的信息最丰富的方法可能是 .executeUpdate(),因为它返回写入语句时受影响的行数;此外,对于成功执行的 DDL,它不会返回 SQL 错误(据我所知,这是成功的唯一指标),并且

PreparedStatement
仍然有一个可检索的
java.sql.ResultSet
用于 SELECT 语句。但除了由于方法的用词不当/滥用而违反各种最佳实践方法之外,这仍然无法清楚地表明所执行语句的类型。

java sql jdbc
1个回答
2
投票

在不广泛解析 SQL 语句的情况下确定 SQL 语句的确切类型可能具有挑战性,特别是当您想要涵盖不同数据库系统中所有可能的 SQL 方言和变体时。 JDBC 和

PreparedStatement
接口不提供直接方法来确定语句类型。

正如您所提到的,检查第一个关键字可能会给您一个粗略的了解,但由于 SQL 方言和专有扩展的多样性,它并不是万无一失的。此外,对所有语句使用

executeUpdate()
并不是一个好的做法,并且不能可靠地指示语句类型。

更可靠的方法是解析 SQL 语句,但这可能很复杂且容易出错。有可用的第三方 SQL 解析器可以帮助解决此问题,但它们可能无法涵盖所有可能的 SQL 变体。

以下是一些注意事项:

  1. 数据库特定功能:某些数据库提供扩展或系统表/函数来确定语句类型。例如,PostgreSQL 有

    pg_stat_statements
    ,Oracle 有
    V$SQL
    用于跟踪 SQL 语句。但是,这些是特定于数据库的解决方案,而不是标准 JDBC 的一部分。

  2. 自定义日志记录:另一种方法是在应用程序中记录 SQL 语句及其类型以进行审计。这样,您就可以记录执行时的语句类型。

  3. 存储过程:将SQL语句封装在存储过程中可以提供更多的控制和审计功能。您可以为不同类型的语句创建存储过程,然后从应用程序中调用这些过程。

  4. 查询生成器:考虑使用查询生成器或对象关系映射 (ORM) 框架(如 Hibernate)。这些工具通常不需要编写原始 SQL 语句,并且可以提供更可靠的方法来执行数据库操作。

总之,虽然没有一种万无一失、与数据库无关的方法来使用

PreparedStatement
确定 SQL 语句的确切类型,但您可以根据您的特定要求和约束组合各种方法。自定义日志记录和特定于数据库的功能可能很有用,但您可能仍然需要依赖某种级别的 SQL 解析或使用框架提供的更高级别的抽象,以使您的代码更加健壮和可维护。

© www.soinside.com 2019 - 2024. All rights reserved.