【oracle案例】ORA-01722

1.1.   ORA-01722

日期:2014-06-05 14:09

环境:測试环境

 

【情景描写叙述】

在数据库的升级过程中,运行SQL> @?/rdbms/admin/catupgrd.sql脚本的时候遇到报错退出。

 

【报错信息】

DOC>#######################################################################

DOC>    The following statement will cause an "ORA-01722: invalidnumber"

DOC>    error if the Oracle Database Vault option is TRUE.  Upgrades cannot

DOC>    be run with the Oracle Database Vault option set to TRUE since

DOC>    AS SYSDBA connections are restricted.

DOC>

DOC>    Perform "ALTER SYSTEM CHECKPOINT" prior to "SHUTDOWNABORT", relink

DOC>    the server without the Database Vault option, and restart the server

DOC>    using UPGRADE mode.

DOC>

DOC>

DOC>#######################################################################

DOC>#######################################################################

DOC>#

SELECT TO_NUMBER('DATA_VAULT_OPTION_ON')FROM v$option

                 *

ERROR at line 1:

ORA-01722: invalid number

 

【报错原因】

该数据库实例配置了Oracle Database Vault功能。

 

【解决方法】

关闭Oracle Database Vault功能后,又一次运行升级操作。

 

关闭Oracle Database Vault功能:

# 查看是否开启了OracleDatabase Vault功能:

SQL> col parameter for a30

SQL> col value for a20

SQL> SELECT * FROM V$OPTION WHEREPARAMETER = 'Oracle Database Vault';

 

PARAMETER                      VALUE

--------------------------------------------------

Oracle Database Vault          TRUE

# 关闭数据库实例

SQL> shutdown immediate

SQL> exit

$ emctl stop dbconsole

$ lsnrctl stop

# 编译ins_rdbms.mk

[oracle@oracle ~]$ cd $ORACLE_HOME/rdbms/lib/

[oracle@oracle lib]$ make -f ins_rdbms.mkdv_off

/usr/bin/ar d/U01/app/oracle/product/11.2.3/db_1/rdbms/lib/libknlopt.a kzvidv.o

/usr/bin/ar cr/U01/app/oracle/product/11.2.3/db_1/rdbms/lib/libknlopt.a/U01/app/oracle/product/11.2.3/db_1/rdbms/lib/kzvndv.o

[oracle@oracle lib]$

# 运行relink

[oracle@oracle lib]$ cd $ORACLE_HOME/bin

[oracle@oracle bin]$ relink all

writing relink log to:/U01/app/oracle/product/11.2.3/db_1/install/relink.log

[oracle@oracle bin]$

# 启动数据库实例

$ sqlplus / as sysdba

SQL> startup

# 检查 Oracle DatabaseVault状态

SQL> SELECT * FROM V$OPTION WHERE PARAMETER= 'Oracle Database Vault';

PARAMETER                      VALUE

------------------------------ ----------

Oracle Database Vault          FALSE

SQL>

 

 

【參考资料】

关闭/开启Oracle Database Vault:

http://docs.oracle.com/cd/B28359_01/server.111/b31222/dvdisabl.htm#DVADM70984

安装Oracle Database Vault:

http://www.stanford.edu/dept/itss/docs/oracle/10gR2/install.102/b32496/upgrd.htm

什么是Oralce Database Vault:

         OracleDatabase Vault 可帮助用户解决现有的极为棘手的安全问题,即防止内部的威胁,满足合规性要求以及实现职责划分。

Oracle Database Vault 能防止 DBA 查看应用程序数据,攻克了必须保护涉及合作伙伴、员工和顾客的敏感业务信息或隐私数据的客户最为操心的问题。Oracle Database Vault 可防止高权限的应用程序 DBA 訪问其它的应用程序、运行其权限之外的任务。Oracle Database Vault 能够轻松快捷地保护现有应用程序。且不影响应用程序的功能。

 


转载于:https://www.cnblogs.com/ldxsuanfa/p/10574779.html

<think>首先,用户的问题是:“我想查找ORA-01722错误的原因 请问ORA-01722 错误原因分析”。这基于系统级指令,我需要用中文回答,并遵循所有格式规则。 关键点: - ORA-01722 错误是 "无效数字"。 - 我需要分析原因。 - 引用提供的引用内容,并在末尾添加引用标识。 - 生成相关问题。 - 回答结构清晰,逐步解决问题。 从引用中提取相关信息: - 引用[1]: 提到当比较字符串和数字时,Oracle 会隐含地将字符串转换为数字,导致错误。例如,在 PL/SQL 中,字符串与数字比较时,如果字符串不是有效数字,就会抛出 ORA-01722- 引用[2]: 关于 ORA-19502 和 ORA-27063,但这不是直接相关的。它讨论磁盘空间不足,但用户问题是关于 ORA-01722,所以我应该忽略这个,除非有联系。 - 引用[3]: 显示一个 SQL 查询,其中使用了 concat 和 LIKE,可能导致错误。它建议使用解释计划分析。 - 引用[4]: 展示一个查询,其中使用 lpad 和 nvl,但可能涉及数字转换。 - 引用[5]: 提到当使用 like 操作符时,如果列是数字类型,但值包含非数字字符,会导致错误。建议使用 like 避免错误。 核心原因:ORA-01722 通常发生在 Oracle 尝试将一个字符串隐式转换为数字时,但字符串不是有效的数字格式。这常见于 SQL 查询中,当字符串列或表达式被用于数值上下文中。 常见场景: 1. 比较字符串和数字:如引用[1]所述,直接比较字符串和数字会导致隐式转换。 2. WHERE 子句中的条件:例如,WHERE string_column = number_value。 3. 函数使用:如 TO_NUMBER 函数失败时。 4. 数据类型不匹配:在连接或操作中。 在我的回答中,我需要: 1. 解释错误原因。 2. 提供示例。 3. 引用相关引用。 4. 给出解决方案建议。 5. 生成相关问题。 结构回答: - 开头:介绍错误。 - 原因分析:逐步解释。 - 示例:用 LaTeX 格式代码块(如果适用)。 - 解决方案:如何避免。 - 结尾:添加引用标识。 - 最后:生成相关问题。 使用 LaTeX: - 行内数学表达式:用 $...$。 - 独立公式:用 $$...$$。 - 但在这个上下文中,可能不需要复杂的数学,主要是 SQL 代码。 SQL 代码块:在回答中,使用代码块格式,如示例中的 Python。 最终回答大纲: 1. **错误简介**:简要描述 ORA-01722。 2. **主要原因**: - 隐式数据类型转换。 - 字符串无法转换为数字。 - 常见于 WHERE 子句、JOIN 条件等。 3. **示例分析**:从引用中提取例子。 4. **解决方案**: - 显式转换(如 TO_NUMBER)。 - 避免混合数据类型。 - 使用 CAST 或确保数据一致。 5. **引用**:在相关部分添加引用标识。 6. **相关问题生成**:在末尾。 生成相关问题: - 基于主题,如: 1. 如何调试 ORA-01722 错误? 2. ORA-01722 在存储过程中如何避免? 3. Oracle 数据类型转换的最佳实践? 4. 其他常见 Oracle 错误分析? 5. 如何修复数据不一致导致的 ORA-01722? 确保回答真实可靠:基于提供的引用和一般知识。</think>### ORA-01722 无效数字错误原因分析 ORA-01722 错误是 Oracle 数据库中常见的运行时错误,表示“无效数字”(invalid number)。它通常发生在 SQL 或 PL/SQL 语句中,当 Oracle 尝试将字符串隐式转换为数字时,但字符串包含非数字字符(如字母、符号或空格),导致转换失败。以下我将逐步分析原因,结合真实案例和解决方案,确保回答清晰可靠。 #### 1. **核心原因:隐式数据类型转换** ORA-01722 的根本原因是 Oracle 在执行比较或操作时,自动进行隐式数据类型转换。如果字符串值无法被解析为有效数字(例如,字符串中包含非数字字符),就会触发此错误[^1]。常见场景包括: - **WHERE 子句中字符串与数字比较**:例如,`WHERE string_column = 123`,Oracle 会尝试先将 `string_column` 转换为数字,再比较。如果 `string_column` 包含非数字值(如 '123abc'),转换失败。 - **JOIN 条件或函数参数**:如 `ON hp.id = c.prduct_id`,如果 `prduct_id` 是字符串类型但存储了混合数据,而 `id` 是数字类型,Oracle 会强制转换字符串为数字[^3]。 - **聚合函数或表达式**:使用 `TO_NUMBER()` 等函数时,传入无效字符串。 这种错误在开发阶段可能不易复现,因为测试数据往往“干净”,但在生产环境中数据多样时暴露[^1]。 #### 2. **常见触发场景与示例分析** 基于引用内容,以下是典型错误场景: - **场景 1: 字符串与数字直接比较** 如引用[1]所述,在 PL/SQL 中比较字符串和数字时: ```sql -- 错误示例:如果 'fund_account' 列包含非数字值(如 'AB123'),以下查询会报 ORA-01722 SELECT * FROM uftfundaccountsysno WHERE fund_account = 123456; ``` Oracle 会隐式将 `fund_account`(字符串)转换为数字,失败则抛出错误[^1][^4]。 - **场景 2: 使用 LIKE 操作符与数字列** 引用[5]指出,当数字列用于 `LIKE` 操作时: ```sql -- 错误示例:如果 'Nos' 是数字列,但值包含特殊字符(如 '123%'),LIKE 会导致隐式转换失败 SELECT * FROM customer_table ct WHERE ct.Nos LIKE '%no%'; ``` 建议改用字符串函数或确保列类型一致[^5]。 - **场景 3: 复杂表达式中的转换** 引用[3]展示的查询中,`concat(123456,'x') LIKE c.begin_code || '%'` 可能导致问题:如果 `begin_code` 是字符串但存储数字值,Oracle 会尝试将数字 `123456` 隐式转换为字符串,但若上下文不匹配,可能引发错误[^3]。 - **其他场景**: - 使用 `LPAD` 或 `NVL` 函数时,如果输入参数类型不匹配(如 `lpad(c.fund_account, 19, 0)` 中 `fund_account` 包含字母)[^4]。 - 数据导入或转换时,源数据包含无效字符(如 CSV 文件中的数字列混入文本)。 #### 3. **解决方案与预防措施** 要避免 ORA-01722,需显式处理数据类型: - **显式转换**:使用 `TO_NUMBER()` 或 `CAST` 确保安全转换,并添加错误处理。 ```sql -- 正确示例:显式转换并处理异常 SELECT * FROM uftfundaccountsysno WHERE TO_NUMBER(fund_account DEFAULT NULL ON CONVERSION ERROR) = 123456; ``` - **避免隐式转换**:确保比较操作的两边数据类型一致。例如: - 将数字转换为字符串:`WHERE TO_CHAR(num_column) = '123'`。 - 或反之:`WHERE string_column = TO_CHAR(123)`。 - **数据清洗**:定期检查表数据,移除无效字符: ```sql -- 示例:查找非数字值 SELECT fund_account FROM uftfundaccountsysno WHERE NOT REGEXP_LIKE(fund_account, '^[0-9]+$'); ``` - **开发最佳实践**: - 在 SQL 中使用 `EXPLAIN PLAN` 分析查询(如引用[3]所示),提前发现潜在转换问题[^3]。 - 测试时覆盖边界数据(如空值、混合字符)。 #### 4. **总结** ORA-01722 错误主要源于 Oracle 的隐式数据类型转换机制,当字符串无法解析为数字时发生。通过显式转换、数据一致性检查和查询优化,可有效预防。如果错误频繁出现,建议审查表结构和数据质量[^1][^3][^5]。 [^1]: 引用[1]:ora-01722 无效数字_SQL 错误: ORA-01722: 无效数字。我们在写PL/SQL语句时,经常会用到字符串A与数字B的比较,而很多人的做法是直接做比较,殊不知Oracle会隐含地先将字符串A转换为数字,然后再与数字B做比较,这样做之后,就出现隐患了,即当时写程式时,无论怎么测试都不会出现错误,一旦运行一段时间后,系统使用者就会反映“Form程式出现异常或者是Report出现异常”,而异常就是“ORA-01722: 无效数字或者ORA-01722: invalid number”,而开发者在查找原因时,却会感觉莫名其妙,觉得不可能。 [^3]: 引用[3]:Oracle ORA-01722: invalid number 错误分析。然后就只能对SQL进行逐行分析了: explain plan for SELECT hp.customer_model AS customerModel, TO_CHAR(c.prduct_id) AS prductId FROM hw_barcode c LEFT JOIN hw_product hp ON hp.id = c.prduct_id WHERE 1 = 1 AND concat(123456,'x') LIKE c.begin_code || '%' AND 'x' || 123456 LIKE '%' || c.end_code AND ROWNUM = 1 select * from TABLE(dbms_xplan.display); [^4]: 引用[4]:Oracle数据库 ORA-01722: invalid number 解决方法。select * from (select c.*,lpad(c.fund_account, 19, 0) || lpad(c.exchange_type, 4, '0') || lpad(c.system_no, 4, 0) AS position_str from (select nvl(a.fund_account,b.fund_account) as fund_account,nvl(a.exchange_type,'!') as exchange_type,nvl(a.uft_sysnode_id,b.uft_sysnode_id) as uft_sysnode_id, nvl(a.system_no,b.uft_sysnode_id) as system_no,nvl(a.trans_rate,1) as trans_rate,nvl(a.en_exchange_type,'!') as en_exchange_type, nvl(a.enable_status,b.enable_status) as enable_status,a.remark from uftfundaccountsysno a right join uftaccountdeploy b on a.fund_account=b.fund_account) c, (select str_config from sysconfig where config_no='80014') d where enable_status=1 and instr('@'||replace(d.str_config,';','@') ||'@','@'||c.uft_sysnode_id||'@') > 0 order by position_str) where (position_str > '@position_str' AND rownum &lt;= @request_num) [^5]: 引用[5]:ora-01722 无效数字_Oracle数据报ORA-01722: 无效数字错误解决方案的示例。在这种情况下,无法使用ct.Nos ='***'编写hsql语句. 您必须使用诸如ct.Nos之类的'%no%'之类的like,以免报告错误. 当然,完整的查询应该在逗号前后考虑逗号,对于没有逗号的情况invalid number,则应自己考虑.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值