plsql里面执行正常,java运行报ORA-01722: 无效数字

本文探讨了在Oracle数据库中,由于SQL执行顺序不当导致的ORA-01722无效数字错误。通过调整WHERE子句中条件的顺序,解决了在使用MyBatis动态SQL时出现的问题,并提高了查询效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

贴代码:

<select id="getInfo" parameterClass="java.util.HashMap" resultClass="java.util.HashMap">
      <isEqual property="Type" compareValue="02">
        select a.*
        from INFO a
      where

    a.TYPE= #Type#
    </isEqual>
     <isEqual property="Type" compareValue="01">
      select a.*
       from INFO a 
     where 

    a.TYPE= #Type#
          and to_number(a.END) >= to_number(#No#) 
     </isEqual>

</select>

当Type为01的时候报错:ORA-01722: 无效数字,,目标锁定and to_number(a.END) >= to_number(#No#) 

但是将SQL复制到数据库执行的时候是可以的

问题原因:

在Type为02的时候a.END里面包含字符,Type为01的时候a.END里面只有数字

因为oracle条件是从下往上筛选的,所以to_number(a.END)在a.TYPE= #Type#之前,导致无效数字错误

处理方式:

将a.TYPE= #Type#条件放到最后

同理:筛选范围最大的条件应该放在最后面,提高执行效率

 

求解:

将SQL复制到数据库执行的时候不管条件是如何顺序都是可以的

如果有人知道的还请指教

 

转载于:https://www.cnblogs.com/zhouyeqin/p/6438834.html

### ORA-01722: Invalid Number 错误的原因及解决方案 #### 问题概述 ORA-01722Oracle 数据库中常见的错误之一,通常发生在尝试将一个无法识别为有效数字的字符串转换为数值时。此错误的核心原因是 `TO_NUMBER` 函数在处理非数字字符串或不符合预期格式的字符串时会引发异常[^1]。 --- #### 错误产生的根本原因 1. **隐式类型转换** 当 SQL 查询中涉及不同类型之间的比较(如 `VARCHAR2` 和 `NUMBER`),Oracle 可能会在后台自动应用隐式的 `TO_NUMBER` 转换。如果目标列包含非数字字符,则会导致 ORA-01722 错误[^2]。 2. **显式使用 TO_NUMBER** 显式调用 `TO_NUMBER` 函数时,若传递给它的字符串不符合指定的格式掩码或者完全是非数字内容,同样会产生该错误[^3]。 3. **JOIN 条件中的类型不一致** 在复杂的查询中,比如连接两个表时,如果一方是字符串而另一方是数字,并且未正确处理类型一致性问题,也可能触发此类错误[^4]。 --- #### 解决方案 ##### 方法一:确保数据的一致性和清洁性 这是最直接也是最重要的预防措施。可以通过以下方式实现: - **数据清洗** 提前筛选掉那些明显不可能成为合法数字的记录。例如,对于可能存在非法值的目标列,可以采用正则表达式或其他工具进行初步过滤。 ```sql WITH cleaned_data AS ( SELECT name FROM test WHERE REGEXP_LIKE(name, '^[+-]?[0-9]+(\.[0-9]*)?$') -- 判断是否为合法数字 ) SELECT * FROM cleaned_data WHERE TO_NUMBER(name) = 1; ``` ##### 方法二:强制控制类型匹配 始终让参与运算的操作数保持相同的数据类型是最安全的做法。具体来说: - **字符串对比字符串** 如果字段本身存储的是字符串形式的编号而非真正的数值型数据,则应避免不必要的类型转换。 ```sql SELECT * FROM test WHERE name = '1'; ``` - **明确声明类型转换规则** 若确实需要跨类型操作,务必主动掌控转换过程而不是依赖系统的默认行为。 ```sql SELECT * FROM test WHERE TO_CHAR(salary) = '1'; -- salary假设是一个number类型的字段 ``` ##### 方法三:利用例外捕获机制 针对已知存在潜在风险的部分,可以设计更稳健的逻辑来包容可能出现的问题情况。例如借助 PL/SQL 中的异常处理器部分屏蔽个别不合规格项的影响范围。 ```plsql DECLARE v_result NUMBER; BEGIN BEGIN v_result := TO_NUMBER('not_a_number'); EXCEPTION WHEN VALUE_ERROR THEN DBMS_OUTPUT.PUT_LINE('Conversion failed!'); END; END; / ``` ##### 方法四:调整 NLS 参数适应本地化需求 有时因为地区习惯的不同(如小数点与千分位符号的选择差异),也会间接造成误解读现象的发生。适时调节相关环境变量有助于缓解这类矛盾冲突状况。 ```sql ALTER SESSION SET NLS_NUMERIC_CHARACTERS = ',.'; -- 修改为欧洲风格的小数表示法 SELECT TO_NUMBER('12.345,67', '99G999D99') FROM DUAL; ``` --- ### 总结 为了防止 ORA-01722 错误的发生,应当注重源头治理——即维持良好的数据质量标准;其次是在编写 SQL 或者程序代码阶段充分考虑到各种边界情形并采取相应的防护手段加以规避;最后还可以通过合理运用数据库自身的特性功能进一步强化整个体系的安全保障能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值