oracle排除某个条件,去除SQL语句某查询条件

2023-05-16

工作需求:根据不同条件查询数据,目前有下拉列表和单选按钮两种

20180614121941595399.png

如果只是查询具体的条件,那很简单,只需要在where 条件之后加上相应的条件即可,像这样:where type = ‘门诊’。当查询的是全选或全部时,显然的就要把相应的条件给去除,如果你是使用mybatis,那也很简单,只需要在xml映射文件里加上一些判断条件,像这样:

select*from user

id=#{id}

and type=#{type}

and gender=#{gender}

但是项目中的需求往往千奇百怪,由于我的SQL语句是写在json配置文件里的,而我又使用的是mybatis框架,我没办法将SQL语句直接写在mybatis的xml映射文件里,我只有把SQL作为一个参数传递给映射文件,就像上面传递id,type,gender一样。

因为我传递的是一句SQL语句而不是具体条件,当我的SQL语句里出现特殊字符如比较字符时XML是会帮我转义的,我不需要XML去转义我的SQL,所以我要使用

将我的SQL语句包裹起来,这样SQL语句就不会被转义了。这里使用${ SQL }而不是#{ SQL },#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号,$将传入的数据直接显示生成在sql中,显然我的SQL语句不需要加双引号。(这里我也先不考虑使用$会导致SQL注入的问题,后期我也会去做SQL检查)

现在背景已经明确,如果想完成需求,我只有在SQL进入XML映射文件之前,将一些条件处理掉。SQL是写在json配置文件里的,预先的条件也是写死的,如下:

"sql":"SELECT nvl(sum(a.ssrc),0) as count FROM CB_ME_YLZL a,CB_DI_DATE b,CB_DI_YLJG c,CB_DI_JZLX d WHERE a.sjid=b.sjid and a.yljgid=c.yljgid and a.jzlxid=d.jzlxid and c.yljgdj=‘3‘ and c.yljgmc = #{select1_val_select} AND type = #{radio1_val_radio}"

当用户选择全选或是全部时,我需要把

and c.yljgmc = #{select1_val_select} AND type = #{radio1_val_radio}

去掉。不是全选或全部时我需要把

#{select1_val_select} 和 #{radio1_val_radio}

替换成相应的条件。

代码如下:

/*** 处理SQL语句

*

*@paramsql

*@return

*/

public staticString dealSQL(String sql, String str) {

sql= sql.trim().toUpperCase().replaceAll(" +", " ");int form = sql.indexOf(" FROM ");

String begin= sql.substring(0, form);

begin= begin.replaceAll(" AS ", " AS C_");

String end=sql.substring(form, sql.length());

sql= begin+end;

String[] split1= str.trim().toUpperCase().replaceAll("‘", "").replaceAll("\"", "").split(",");for(String s : split1) {if(StringUtils.isNotBlank(s)) {

String[] split2= s.split(":");if(sql.contains(split2[0])) {if(split2[0].contains("VAL_RADIO") || split2[0].contains("VAL_SELECT")) {if(split2[1].equals("全选") || split2[1].equals("全部")) {

sql= removeSQL(sql,"#{"+split2[0]+"}");

}else{

sql= sql.replace("#{"+split2[0]+"}", "‘" + split2[1] + "‘");

}

}else{

sql= sql.replace("#{"+split2[0]+"}", "‘" + split2[1] + "‘");

}

}

}

}returnsql;

}

json配置文件里规定需要展现的字段都要使用as ** 作为别名,但是如果别名为数字或特殊字符的话,oracle是不认的,如果别名使用双引号引起来,orace认但json文件又不认了,所以我使用最low的办法,将所有别名加上一个C_,这样数据库就认了。

看一下  removeSQL方法:

/*** 去除SQL语句某查询条件

*@paramsql

*@paramchoice

*@return

*/

public staticString removeSQL(String sql,String choice) {int cho_first =sql.indexOf(choice);int before_and = sql.lastIndexOf(" AND ", cho_first);int before_where = sql.lastIndexOf(" WHERE ", cho_first);int after_and = sql.indexOf(" AND ", cho_first);int after_where = sql.indexOf(" WHERE ",cho_first);if(before_where != -1) {if(before_and != -1) {if(before_and >before_where) {

sql= sql.replace(sql.substring(before_and, cho_first), " ").replace(choice, " ");

}else{if(after_and != -1) {if(after_where != -1) {if(after_and

sql= sql.replace(sql.substring(before_where+7, after_and+5), " ");

}else{

sql= sql.replace(sql.substring(before_where, cho_first), " ").replace(choice, " ");

}

}else{

sql= sql.replace(sql.substring(before_where+7, after_and+5), " ");

}

}else{

sql= sql.replace(sql.substring(before_where, cho_first), " ").replace(choice, " ");

}

}

}else{if(after_and != -1) {if(after_where != -1) {if(after_and

sql= sql.replace(sql.substring(before_where+7, after_and+5), " ");

}else{

sql= sql.replace(sql.substring(before_where, cho_first), " ").replace(choice, " ");

}

}else{

sql= sql.replace(sql.substring(before_where+7, after_and+5), " ");

}

}else{

sql= sql.replace(sql.substring(before_where, cho_first), " ").replace(choice, " ");

}

}

}returnsql;

}

逻辑也就是:当条件在不同地方,处理方式不同而已,下面是几种罗列的可能存在条件的地方,上面代码就是针对这些不同地方,将这些条件连同其前的and或者where(不影响其后的and条件使用的where,如下图第二条语句第一处位置的条件)去掉。(针对复杂的SQL,如使用with as 将查询数据做临时表,之后再使用select查询临时表的,这些代码是不能处理的)

20180614121941760428.png

原文:https://www.cnblogs.com/liudaihuablogs/p/9181949.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

oracle排除某个条件,去除SQL语句某查询条件 的相关文章

  • 递归 SQL 给出 ORA-01790

    使用 Oracle 11g 第 2 版 以下查询给出 ORA 01790 表达式必须与相应表达式具有相同的数据类型 with intervals time interval AS select trunc systimestamp from
  • Oracle 9i:同义词表不存在?

    我创建了一个包 其中包含一个存储过程 我计划从单独的应用程序调用该存储过程 存储过程将返回架构中所有视图和表的排序列表 为此 它对 DBA TABLES 和 DBA VIEWS 同义词执行简单的选择 如下所示 CREATE OR REPLA
  • 从表中删除孤儿

    我正在尝试清理一张有很多孤立项目的桌子 我通过查找空值来检查是否与另一个表存在关系来解决此问题 DELETE FROM table1 LEFT JOIN table2 ON table1 ID table2 ID WHERE table2
  • 如何授予所有表的 REFERENCES 权限

    我必须授予REFERENCES登录权限说sql login 我可以给予资助REFERENCES对单个表的权限 例如 GRANT REFERENCES ON Mytable TO sql login 有什么办法可以授予REFERENCES允许
  • 如何在 sqlalchemy 中创建基于文字的查询?

    我创建了一个函数来创建表达式 def test operator1 operation operator2 return literal column operator1 op operation operator2 现在当我用 test
  • 如何有效地从 DB2 表中删除所有行

    我有一个大约有 50 万行的表 我想删除所有行 如果我做简单的delete from tbl 事务日志已满 我不关心这种情况下的事务 无论如何我都不想回滚 我可以删除许多事务中的行 但是有更好的方法吗 如何有效地从 DB2 中的表中删除所有
  • SQL参数化查询不显示结果

    我的 DataAcess 类中有以下函数 但它没有显示任何结果 我的代码如下 public List
  • java mysql 准备好的语句

    我正在尝试使用 java 向数据库中进行简单的插入 它告诉我我的 sql 语法已关闭 但是 当我复制打印出来的字符串并将其放入 phpmyadmin 中的 sql 命令中时 它会正确执行该命令 并且我似乎无法弄清楚 java 中的字符串查询
  • 使用两个日期之间的随机日期时间更新每一行

    我有一个专栏叫date created我希望每一行保存一个随机日期 日期距当前时间为 2 天 我正在运行以下查询 但它会更新具有相同随机日期的所有行 我希望每一行都是随机的并且不相同 update table set date create
  • 如何在 SQL Server 中使用 nvarchar 变量为 unicode 用户添加前缀“N”?

    如何在 SQL Server 中使用 nvarchar 变量为 unicode 用户添加前缀 N 例如 给定这个变量 declare Query1 nvarchar max 我可以这样分配它 set Query1 N 但是如果我想使用怎么办
  • 将 UUID 存储为 base64 字符串

    我一直在尝试使用 UUID 作为数据库键 我希望占用尽可能少的字节数 同时仍然保持 UUID 表示形式的可读性 我认为我已经使用 base64 将其减少到 22 个字节 并删除了一些尾随的 这些 对于我的目的来说似乎没有必要存储 这种方法有
  • 如何在 Visual Studio 中更改 Azure 数据库表的列顺序

    我整个下午都在寻找在 MS Visual Studio 2022 中重新排序 Azure 数据库表列的方法 没有运气 在其他应用程序中 可以通过拖动或剪切和粘贴轻松重新排列列 这里无能为力 此时 我什至不确定可以在 VS 中移动列 我只对
  • SQL 删除表并重新创建并保留数据

    在我们最初的设计中 我们搞砸了表中的外键约束 现在表已充满数据 我们无法在不删除表中所有记录的情况下更改它 我能想到的唯一解决方案是创建一个备份表并将所有记录放在那里 然后删除所有记录 更改表并开始将它们添加回来 还有其他 更好 的想法吗
  • Oracle - 使用 DBMS_MVIEW.REFRESH 刷新“REFRESH FORCE ON DEMAND”视图时会发生什么

    我有以下物化视图 CREATE MATERIALIZED VIEW TESTRESULT ON PREBUILT TABLE WITH REDUCED PRECISION REFRESH FORCE ON DEMAND WITH PRIMA
  • 在sqlite SQL语句中与order by子句结合使用limit

    下面的两条 SQL 语句总是会产生相同的结果集吗 1 SELECT FROM MyTable where Status 0 order by StartTime asc limit 10 2 SELECT FROM SELECT FROM
  • sql server 按组排名

    问题看似简单 但我却无法理解 这是针对 sql 服务器的 what I have in a table What I need as a output cksum id cksum id 2162514679 204 2162514679
  • 如何在 PostgreSQL 中使用具有多个值的 SQL LIKE 条件?

    有没有更短的方法来查找多个匹配项 SELECT from table WHERE column LIKE AAA OR column LIKE BBB OR column LIKE CCC 这个问题适用于 PostgreSQL 9 1 但如
  • 使用 where 进行 select 语句时,HSQLDB 用户缺乏权限或未找到对象错误

    我的数据库使用 SQuirrel SQL 客户端版本 3 5 3 和 HSQLDB 我已经能够为其指定相应的驱动程序 内存中 并创建一个别名 我创建了一个表 CREATE TABLE ENTRY NAME VARCHAR 100 NOT N
  • 在 SQL 数据库中存储“列表”的最正确方法是什么?

    因此 我读了很多关于如何将多个值存储到一个列中是一个坏主意 并且违反了数据标准化的第一条规则 令人惊讶的是 这不是 不要谈论数据标准化 所以我需要一些帮助 目前我正在为我工 作的地方设计一个 ASP NET 网页 我想根据此人所属的 Act
  • Laravel leftJoin 仅右表的最后一条记录

    我是 Laravel 的新手 我有两张桌子 1 产品 2 价格 products id product int p key name varchar prices id price int p key id product int

随机推荐