## 简介 记录在使用`oracle`过程在遇到的一些问题,我所用的操作系统是`kali rolling` ## 问题如下 * 在安装过程中遇到的监听器打开失败的问题 在`$ORACLE_HOME/network/admin/listerer.ora`中添加 ``` STENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = zeek)(PORT = 1521)) (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521)) ) ) ADR_BASE_LISTENER = /home/u01/app/oracle ``` 在`$ORACLE_HOME/network/admin/tnsnames.ora`中添加 ``` ORAL = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST =zeek)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = ORAL) ) ) ``` 在`/etc/hosts`中添加 (或者在`listener.ora`中host直接写成ip) ``` 127.0.0.1 zeek ``` * 在创建表的过程中报错 ``` ORA-65096: invalid common user or role name ``` 产生原因是没有指定数据库,主要出现在可插拔式数据库中 解决方案 ```sql select con_id,dbid,name,open_mode from v$pdbs; ``` 得到 ``` CON_ID DBID NAME OPEN_MODE 2 3159417430 PDB$SEED READ ONLY 3 874804722 ORALP MOUNTED ``` 接着在输入 ```sql alter session set container=ORALP; ``` * 数据库实例没注册到listener 报错信息如下,主要出现在用`sqlplus`或者`plsql`登录时报错 ``` ORA-12514: TNS:listener does not currently know of service requested in connect descriptor ``` 在listener.ora里面添加了一行 ``` SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (GLOBAL_DBNAME = ORAL) (SID_NAME = ORAL) ) ) ``` * scott.emp 表不存在 造成这个问题的原因是scott用户没有解锁,所以解决这个问题的办法就是解锁scott用户: 执行脚本`/rdbms/admin/utlsampl.sql `(执行这个脚本的脚本是因为在12c中可能没有这个用户) 接着执行下面语句 ```sql alter user scott account unlock; alter user scott identified by tiger; commit; ``` * 在执行`lsnrctl start`的时候出现如下报错 ``` TNS-12535: TNS:operation timed out TNS-12560: TNS:protocol adapter error TNS-00505: Operation timed out ``` 很可能是你自己不小心将`/etc/hosts` 的`127.0.0.1 zeek `删掉了,补上即可 * `dbms_output.put_line('content' )`中文乱码 在`~/.zshrc`或者`~/.bashrc`或者`/etc/profile` 中添加`export NLS_LANG="AMERICAN_AMERICA.ZHS16GBK"` * 操作临时表时报错信息如下 ``` ORA-14452: attempt to create, alter or drop an index on temporary table already in use ``` 解决办法:执行下面sql语句,得到一个sql语句,执行语句即可 ```sql select 'alter system kill session '''||sid||','||serial#||'''' from v$session where sid in ( select sid from v$lock where id1 in ( select object_id from dba_objects where object_name in ( select table_name from dba_tables where owner='EODA') ) ); ``` * sqlplus 中文字符显示乱码或者显示? 登陆ORACLE ```sh sqlplus eoda/foo ``` 查询当前的数据库的字符集 ```sql SELECT * FROM nls_database_parameters t WHERE t.parameter = 'NLS_CHARACTERSET'; ``` 我的ORACLE查询的结果`AL32UTF8` 在`.bash_profile`中配置(如果想要在除oracle用户下面也正常使用则需要在终端的配置文件里面添加下面内容) ``` export NLS_LANG="AMERICAN_AMERICA.AL32UTF8" ``` * oracle 报错资源忙,报错信息如下 ``` ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired ``` 解决方案 ```sql select session_id from v$locked_object; SELECT sid, serial#, username, osuser FROM v$session where sid = 142; -- sid 的值是上条语句查询出来的 ALTER SYSTEM KILL SESSION '142,38'; -- 值是 sid,serial# ``` * 修改会话支持pdml时,报错详细信息如下 ``` ORA-12841: Cannot alter the session parallel DML state within a transaction ``` 造成错误的主要原因是会话中存在未提交的事务,只需要在提交事务就行 ```sql commit; alter session enable parallel dml; ``` * 在已经支持了pdml的会话中查看执行计划时,报错详细信息如下 ``` ORA-12838: cannot read/modify an object after modifying it in parallel ``` 造成错误的原因是存在未提交的事务 ```sql commit; explain plan for update big_table set status = 'done'; select * from table(dbms_xplan.display(null,null, 'BASIC +PARALLEL')); ``` * 在对varchar2类型的字符串进行trim操作之后比较是否相等,需要注意trim结果是否为null ```sql -- 比较字符串是否相同,执行结果为same begin IF trim(' ') <> trim('1') THEN dbms_output.put_line(' not same'); ELSE dbms_output.put_line('same'); END IF; END; / ``` 可以选择使用 ```sql select decode(trim(' '),trim('1'),'same','not same') from dual; ```