20211016-Oracle 记一次ORA-00001问题处理

在这里插入图片描述

问题现象:

insert all方式插入数据提示如下:

ORA-00001: unique constraint (C##CJC.SYS_C008089) violated

经检查插入的列并没有重复的值。

问题原因:

中文字段有主键约束,由于插入数据库时中文乱码,中文字符全部变成"?",导致相同长度的中文字段被识别为重复数据,导致无法插入。

解决方案:

正确配置NLS_LANG环境变量。

问题重现过程:

1.创建表t1

SQL> show user
USER is "C##CJC"
create table t1(t_name varchar2(300),t_status varchar2(5),primary key(t_name));

2.插入数据

insert all
into t1 values('人生七十古稀,','1')
into t1 values('我年七十为奇。','1')
into t1 values('前十年幼小,','1')
into t1 values('后十年衰老;','1')
into t1 values('中间只有五十年,','1')
into t1 values('一半又在夜里过了。','1')
into t1 values('算来只有二十五年在世','1')
into t1 values('受尽多少奔波烦恼。','1')
select 1 from dual;

报错如下:

ERROR at line 1:
ORA-00001: unique constraint (C##CJC.SYS_C008089) violated

报错信息:

[oracle@cjcos02 ~]$ oerr ora 00001
00001, 00000, "unique constraint (%s.%s) violated"
// *Cause: An UPDATE or INSERT statement attempted to insert a duplicate key.
//         For Trusted Oracle configured in DBMS MAC mode, you may see
//         this message if a duplicate entry exists at a different level.
// *Action: Either remove the unique restriction or do not insert the key.

为什么插入的t_name没有重复字,但是报错ORA-00001呢?

没有插入成功

SQL> col t1_name for a30
SQL> select * from t1;
no rows selected

尝试逐条插入
第一条可以正常插入

SQL> insert into t1 values('人生七十古稀,','1');
1 row created.

第二条插入报错ORA-00001

SQL> insert into t1 values('我年七十为奇。','1');
insert into t1 values('我年七十为奇。','1')
*
ERROR at line 1:
ORA-00001: unique constraint (C##CJC.SYS_C008089) violated

第三条可以正常插入

SQL> insert into t1 values('前十年幼小,','1');
1 row created.

第四条插入报错ORA-00001

SQL> insert into t1 values('后十年衰老;','1');
insert into t1 values('后十年衰老;','1')
*
ERROR at line 1:
ORA-00001: unique constraint (C##CJC.SYS_C008089) violated

查看插入结果

SQL> col t_name for a30
SQL> select * from t1
T_NAME        T_STA
------------------------------ -----
?????????????????????        1
??????????????????        1

检查NLS_LANG配置

空,当前没有设置。

[oracle@cjcos02 dbs]$ echo $NLS_LANG
[oracle@cjcos02 dbs]$ echo $LANG
en_US.UTF-8

查看xshell字符集
文件—属性—终端—编码
当前是:Unicode(UTF-8)

检查Oracle数据库服务器字符集(服务器端):
即Oracle以哪种字符编码存储字符

NLS_LANGUAGE为:AMERICAN
NLS_CHARACTERSET为:AL32UTF8 
col PARAMETER for a30
col VALUE for a30
set pagesize 100
select * from v$nls_parameters where parameter = 'NLS_CHARACTERSET';
PARAMETER        VALUE   CON_ID
------------------------------ ------------------------------ ----------
NLS_CHARACTERSET        AL32UTF8         1

col PARAMETER for a30
col VALUE for a30
set pagesize 100
select PARAMETER,VALUE from nls_database_parameters;
PARAMETER        VALUE
------------------------------ ------------------------------
NLS_RDBMS_VERSION        19.0.0.0.0
NLS_NCHAR_CONV_EXCP        FALSE
NLS_LENGTH_SEMANTICS        BYTE
NLS_COMP        BINARY
NLS_DUAL_CURRENCY        $
NLS_TIMESTAMP_TZ_FORMAT        DD-MON-RR HH.MI.SSXFF AM TZR
NLS_TIME_TZ_FORMAT        HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_FORMAT        DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_FORMAT         HH.MI.SSXFF AM
NLS_SORT        BINARY
NLS_DATE_LANGUAGE        AMERICAN
NLS_DATE_FORMAT         DD-MON-RR
NLS_CALENDAR        GREGORIAN
NLS_NUMERIC_CHARACTERS        .,
NLS_NCHAR_CHARACTERSET        AL16UTF16
NLS_CHARACTERSET        AL32UTF8
NLS_ISO_CURRENCY        AMERICA
NLS_CURRENCY        $
NLS_TERRITORY        AMERICA
NLS_LANGUAGE        AMERICAN
20 rows selected.

检查客户端操作系统字符集:
即客户端操作系统以哪种字符编码存储字符。
:为AMERICAN_AMERICA.AL32UTF8

userenv函数返回当前会话(session)的相关信息。

SQL> select userenv('language') from dual;
USERENV('LANGUAGE')
----------------------------------------------------
AMERICAN_AMERICA.AL32UTF8

返回格式language_territory.characterset

配置NLS_LANG
格式:

NLS_LANG=<Language>_<Territory>.<Clients Characterset> 
LANGUAGE指定: 
-Oracle消息使用的语言 
-日期中月份和日显示 
TERRITORY指定 
-货币和数字格式 
-地区和计算星期及日期的习惯 
CHARACTERSET: 
-控制客户端应用程序使用的字符集

配置:

[oracle@cjcos02 dbs]$ export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
[oracle@cjcos02 dbs]$ echo $NLS_LANG
AMERICAN_AMERICA.AL32UTF8

再次插入数据

sqlplus c##cjc/******
SQL>
insert all
into t1 values('人生七十古稀,','1')
into t1 values('我年七十为奇。','1')
into t1 values('前十年幼小,','1')
into t1 values('后十年衰老;','1')
into t1 values('中间只有五十年,','1')
into t1 values('一半又在夜里过了。','1')
into t1 values('算来只有二十五年在世','1')
into t1 values('受尽多少奔波烦恼。','1')
select 1 from dual;
8 rows created.
SQL> col t_name for a30
SQL> Select * from t1;
T_NAME        T_STA
------------------------------ -----
人生七十古稀,                 1
我年七十为奇。                 1
前十年幼小,                   1
后十年衰老;                   1
中间只有五十年,               1
一半又在夜里过了。             1
算来只有二十五年在世           1
受尽多少奔波烦恼。             1
8 rows selected.
SQL> commit;
Commit complete.

插入成功
#####chenjuchao 20211016 14:35#####
欢迎关注我的公众号《IT小Chen

<think>嗯,用户问的是Oracle数据库ORA-00030错误,我需要先回忆一下这个错误的具体信息。ORA-00030通常和会话被终止有关,可能涉及资源限制或强制操作。我得确认错误代码的正确解释,避免混了其他类似代码。 首先,我应该检查Oracle官方文档中的错误代码部分,确保信息准确。ORA-00030的官方描述是“会话ID不存在”,这可能发生在尝试终止一个不存在的会话时。比如,执行ALTER SYSTEM KILL SESSION命令时提供的SID和SERIAL#不正确,或者会话已经被终止了。 接下来,用户遇到这个错误时,可能需要检查他们使用的SID和SERIAL#是否正确。我需要引导他们如何查询现有的会话信息,比如通过V$SESSION视图。此外,还要考虑是否有权限问题,或者是否在RAC环境中需要指定INST_ID。 另外,ORA-00030和ORA-00031的区别也很重要。ORA-00031是标要终止的会话,而ORA-00030是会话不存在,这点需要明确说明。用户可能在终止会话时混淆了这两个错误,所以需要区分清楚。 然后,应该提供具体的解决步骤。比如,先确认会话是否存在,再检查权限,如果是RAC环境如何处理,以及使用IMMEDIATE选项的情况。还要提醒用户谨慎操作终止会话,避免影响生产环境。 可能用户在实际操作中遇到了问题,例如多次尝试终止同一个会话,导致第二次执行时出现ORA-00030,因为会话已经被终止了。这时候需要建议他们重新查询当前活动会话,确保使用正确的参数。 另外,是否需要考虑其他可能性?比如Oracle版本不同导致的行为差异,或者是否存在bug。如果有相关的补丁或文档说明,最好提及,但如果没有足够信息,可能需要建议查看官方文档或联系支持。 最后,总结错误原因和解决方法,结构清晰,分步骤说明,帮助用户逐步排查问题。确保回答准确、实用,避免技术性错误,同时用中文通俗易懂地表达出来。</think>Oracle数据库ORA-00030错误属于会话控制类错误,其官方定义为: **ORA-00030: Session ID does not exist** 即**会话ID不存在**。以下是逐步解析与解决方法: --- ### 错误原因 此错误通常发生在以下场景: 1. **终止无效会话**:尝试通过`ALTER SYSTEM KILL SESSION`命令终止一个不存在的会话(如已断开会话或错误的`SID`和`SERIAL#`组合)。 2. **参数错误**:提供的会话标识符(`SID`和`SERIAL#`)与实际数据库中的活动会话不匹配。 3. **RAC环境问题**:在Oracle RAC(集群)环境中未指定`INST_ID`,导致无法定位目标会话。 --- ### 复现示例 假设执行以下命令时使用了无效参数: ```sql ALTER SYSTEM KILL SESSION '123,45678'; -- SID=123, SERIAL#=45678 ``` 若会话`123,45678`不存在或已被终止,则会触发ORA-00030。 --- ### 解决步骤 #### 1. 确认会话是否存在 查询当前所有活动会话: ```sql SELECT sid, serial#, username, status, machine, program FROM v$session WHERE type = 'USER'; ``` 检查目标会话的`SID`和`SERIAL#`是否存在于结果中。 #### 2. 检查权限 确保执行终止操作的用户具有`ALTER SYSTEM`权限: ```sql GRANT ALTER SYSTEM TO your_user; -- 若无权限需管理员授权 ``` #### 3. RAC环境处理 若为Oracle RAC,需指定`INST_ID`: ```sql ALTER SYSTEM KILL SESSION 'sid,serial#,@inst_id' IMMEDIATE; -- 例如:ALTER SYSTEM KILL SESSION '123,45678,@1' IMMEDIATE; ``` #### 4. 使用IMMEDIATE选项 强制终止会话时添加`IMMEDIATE`选项: ```sql ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE; -- 此命令会立即终止会话,无需等待事务回滚 ``` --- ### 注意事项 - **ORA-00030与ORA-00031的区别**: - ORA-00030:会话不存在(参数错误)。 - ORA-00031:标要终止的会话(会话存在但无法立即终止)。 - 终止会话可能导致事务回滚,影响业务连续性,请谨慎操作。 --- ### 总结 ORA-00030的核心问题是**无效的会话标识符**。通过查询`v$session`验证会话信息,并确保操作命令参数正确即可解决。若问题持续,需进一步检查数据库日志(`alert.log`)排查环境或权限异常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值