【问题标题】:How to determine type of the sql query for jdbcTemplate in JAVA?如何确定 JAVA 中 jdbcTemplate 的 sql 查询类型?
【发布时间】:2019-02-13 13:32:22
【问题描述】:

我的要求是我想确定 sql 查询的类型,以便我可以相应地选择 jdbcTemplate 方法。

假设我的 sql 查询是 insert 或 update 类型,那么我会选择

String sql ="insert/update sql query";
jdbcTemplate.update(sql); 

jdbcTemplate 方法,如果选择我的 sql 查询类型,那么我会选择

String sql ="select sql query";
jdbcTemplate.query(sql);

jdbcTemplate 方法。

如何有效判断java中sql查询的类型?

如果我的查询同时包含 update 和 select sql 语句,选择哪种 jdbcTemplate 方法?例如

update table set column_name="abc" where column_name in (select column_name from table where column_name ="xyz");

更新: 实际上,我正在接受来自我的应用程序用户的 sql 查询,这就是实际问题出现的原因,因为用户可以通过表单发布任何类型的 sql 查询,并且我想根据查询类型选择特定的 jdbcTemplate 方法。

【问题讨论】:

  • 问题是我想根据 sql 查询类型选择特定的 jdbcTemplate 方法
  • 出于什么目的?假设您编写了一个执行此操作的方法,如果我正在调用您的方法,那么我仍然需要知道是否期望结果是单个对象、集合或什么都没有。我看不出这有什么用。
  • Michael 为了问题的简单性,我已经发布了这样的内容,实际上我正在接受来自表单的用户的 sql 查询。因此用户可以发布任何类型的 sql 查询。
  • 小心小鲍比桌。

标签: java sql spring oracle jdbctemplate


【解决方案1】:

在 Oracle 中,您可以在执行查询之前对其进行解析

declare
    l_theCursor     integer default dbms_sql.open_cursor;
begin
    dbms_sql.parse(  l_theCursor,  'SELECT 1 FROM DUAL', dbms_sql.native );
end;

无论如何,这是一个很好的做法,因为您将从用户输入中接收 SQL。如果语句无效,您将收到相应的错误消息。当然上面的语句不是执行的。

解析语句后可以查询v$sql找出command_type:

select command_type, sql_text
from v$sql t
where sql_text = 'SELECT 1 FROM DUAL';

各种command_types如下:

2 -- 插入

3 -- 选择

6 -- 更新

7 -- 删除

189 -- 合并

您可以通过select * from audit_actions order by action获取完整列表

希望对你有帮助:)

【讨论】:

  • 好主意。使用 Oracle 12 DBMS_SQL_TRANSLATOR.SQL_ID 是否可以在解析 PL/SQL 块中计算 SQL_ID,这使得访问 V$SQL 更加舒适。
  • @MarmiteBomber 感谢您的评论。一种低保真老派的方式也是为每个查询添加一个带有唯一标识符的评论,然后轻松查询
【解决方案2】:

SELECT 子查询与最终结果无关。所以命令,第一个动词表示结果(int updateCount vs. ResultSet)。

boolean isSqlSelect = sql.toUpperCase().startsWith("SELECT")
                   || sql.toUpperCase().startsWith("WITH");

【讨论】:

  • 第一个动词是什么意思,为什么 SELECT 子查询不相关?
  • select 也可以以 with 开头
  • 一个 INSERT ... (SELECT ...) 只是返回一个更新计数,子选择是一个中间产品。
  • 那么我应该为 INSERT ... (SELECT ...) 类型的查询选择 jdbcTemplate.update(sql) 方法吗?
  • @PawanPatil 是的 INSERT 和 UPDATE 都返回更新计数。请参阅提供 ResultSet executeQuery (SELECT) 或 int executeUpdate(SQL 更改)的 JDBC PreparedStatement。 JdbcTemplate 建立在这个基础之上。
【解决方案3】:

您可以通过 .select() 方法运行 SQL UPDATE 查询,也可以通过 .update() 方法运行 SQL SELECT 查询。

那么为什么会有两种不同的方法呢?

update 方法返回单个数字;此数字表示更改/创建的行数。

select 方法返回一个结果集,它就像一个小表格:它有许多(类型化和命名的)列,您可以遍历结果集,每次获取一行的数据。

实际上,通过 .update() 运行 SELECT SQL 语句将运行 select(如果该 select 以某种方式写入数据库,例如因为您运行 SELECT NEXTVAL('someSequence'),这些效果确实会发生,但是你得到 0 回来,因为它没有改变/添加任何行到任何表。如果你通过 .select() 运行 UPDATE SQL,更新会通过,你会得到一个空的结果集,或者可能是一个有 1 列的结果集某种数字类型,一行,该行的一个值等于更新计数。这取决于 JDBC 驱动程序。

还有另一种方法(执行),它什么也不返回。此处同样适用:如果您通过此方法运行 UPDATE,它仍然有效,只是您无法取回更新计数。

我的建议:全部使用 .select,并编写一个漂亮的渲染器,将结果集报告给用户。

如果您想调查一些已经完成所有这些工作的代码,请查看h2 console

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-01
    • 1970-01-01
    • 2016-03-17
    • 2021-06-11
    • 2020-12-26
    相关资源
    最近更新 更多