Oracle數據庫操作


Oracle文檔

導入導出

Oracle數據庫備份操作建議使用數據泵方式(expdp/impdp),效率高,並且可選參數豐富

expdp/impdp

數據泵導入導出方式有directory的概念,select * from dba_directories;dmp存放位置需要配置directory,
另外直接放到oracle安裝目錄的默認導入導出目錄下則不需要配置。路徑為oracle安裝目錄/admin/${sid}/dpdump/

  • expdp

    • expdp user/passwd@localhost:1521/orcl dumpfile=exp.dmp logfile=exp.log --導出user用戶下對象
    • DATA_ONLY=y 只導入/導出表數據
    • METADATA_ONLY=y 只導入/導出對象定義
    • full=y 全庫導出,需要擁有dba或者exp_full_database導出權限
    • schemas=user 導出一個或多個對象
    • Tablespaces=tab1 導出一個或多個表空間
    • tables=tab1,tab2 導出指定表
    • query=\"where id < 100000 \" 使用query導出部分數據,id小於100000
    • Sample=10 導出10%數據(近似參考值)
    • EXCLUDE/INCLUDE 注意:在windows使用時雙引號需要轉義,Linux中單雙引號和括號都需要轉義,並且所有數據需要大寫 expdp fms_cloud/fms_cloud INCLUDE=TABLE:\"='T8_BOND_DEAL_INFO'\" dumpfile=include.dmp --windows
      expdp fms_cloud/fms_cloud INCLUDE=TABLE:\"=\'T8_BOND_DEAL_INFO\'\" --Linux
    • EXCLUDE=SEQUENCE,VIEW --過濾所有的SEQUENCE,VIEW
    • EXCLUDE=TABLE:"IN ('EMP','DEPT')" --過濾表對象EMP,DEPT
    • EXCLUDE=SEQUENCE,VIEW,TABLE:"IN ('EMP','DEPT')" --過濾所有的SEQUENCE,VIEW以及表對象EMP,DEPT
    • EXCLUDE=INDEX:"= 'INDX_NAME'" --過濾指定的索引對象INDX_NAME
    • INCLUDE=PROCEDURE:"LIKE 'PROC_U%'" --包含以PROC_U開頭的所有存儲過程(_ 符號代表任意單個字符)
    • INCLUDE=TABLE:"> 'E' " --包含大於字符E的所有表對象
  • impdp

    • impdp user/passwd@localhost:1521/orcl dumpfile=exp.dmp logfile=imp.log --將exp.dmp導入到user用戶下
    • Table_exists_action=(SKIP/APPEND/TRUNCADE/REPLACE) 導入表存在處理(跳過/追加數據/清空並追加/替換表)
    • REMAP_SCHEMA=fromuser1:touser,fromuser2,touser 導入切換用戶,從多個用戶切換到touser
    • REMAP_TABLESPACE=fromtabspace1:totabspace,fromtabspace2:totabspace 導入切換表空間,多個表空間切換
    • 導入部分表替換已存在表並切換用戶和表空間 例:impdp fms_jc/fms_jc dumpfile=fmsdev20200429.dmp REMAP_SCHEMA=fmsdev:fms_jc REMAP_TABLESPACE=fmsdev_data:fms_jc TABLES=fmsdev.T8_SYS_EXPRESSION,fmsdev.T8_SUBJECT_ACCRULE,fmsdev.T8_SUBJECT_POOL,fmsdev.T8_SUBJECT_CTRL Table_exists_action=REPLACE

exp/imp

  • exp username/password@localhsot/orcl file='/user/oracle/tmp.dmp' --導出用戶數據表結構
  • exp fms_cloud/fms_cloud@oracle-dev.zcgl.kkws.cn/xe file='D:\KKWS腳本\dmp\exp.dmp' TABLES=(ACT_WORKFLOW_FORM)QUERY=\"WHERE rownum<10000\" --導出用戶指定表數據到指定位置
  • imp username/password@localhost/orcl file='/usr/oracle/tmp.dmp' full=y ignore=y log=imp.log --將tmp.dmp文件導入到用戶中,full=y表示全部導入 ignore=y表示忽略創建錯誤繼續執行
    • data_only=y 只導數據
    • rows=n 不導入數據
    • fromuser=user1 touser=user2 導入時切換用戶(在ignore=y不生效時可使用)
    • tables=(tab1,tab2) 導出指定表
    • QUERY=\"WHERE rownum<11\" 在tables()后面跟上導出部分數據

SQL語法

DML數據操作語言

基本功能

增刪改查
  • insert into table_name (column1,column2,column3) values (1,2,3); --插入數據
  • select column_name from table_name; --查詢表數據
  • update table_name set column_1 = newdata where id = 1; --修改表數據
  • delete from table_name where id = 1; --刪除表數據

插入數據字段拼接單引號

  • insert into table_name(column1,column2) values ('測試1','測試2');
  • insert into table_name(column1,column2) values ('''' || '測試1' || '''','''' || '測試2' || '''');
表備份,恢復
  • create table user_bak as select * from user --表備份
  • truncate table user --清空表
  • insert into user select * from user_bak --插入備份數據
  • drop table user_bak --刪除備份表

輔助功能

數據庫相關
  • select 'create or replace synonym ' || table_name || ' for FMS_CZ_MD.' || table_name || ';' from user_tables;--同義詞創建
  • select userenv('language') from dual; --查看字符集編碼
  • select * from all_users; --查詢所有用戶
  • select * from dba_users;
  • select user from dual; --查詢當前登錄用戶
  • select name from v$database; --查詢當前實例
  • select * from dba_sys_privs;
  • select * from user_sys_privs; (查看當前用戶所擁有的權限)
  • select tablespace_name from sys.dba_tablespaces;--查詢所有表空間
  • select osuser, a.username, cpu_time/executions/1000000||'s', b.sql_text, machine
  • from v$session a, v$sqlarea b
  • where a.sql_address =b.address
  • order by cpu_time/executions desc; --查看當前有哪些用戶正在使用數據庫
  • Oracle的連接數(sessions)與其參數文件中的進程數(process)有關。sessions=(1.1*process+5)
  • select count(*) from v$session; -- 查詢當前的session會話連接數
  • select count(*) from v$process ; --查看當前數據庫進程連接數
  • select value from v$parameter where name ='processes'; --查詢數據庫允許的最大進程連接數
  • select count(*) from v$session where status='ACTIVE'; --查詢數據庫的並發連接數
  • alter system kill session 'sid, serial#'; --殺死某個連接session會話
  • alter system set sessions=1105 scope=spfile; -- 修改允許最大會話連接,需要重啟數據庫
  • alter system set processes = 1000 scope = spfile; --修改數據庫最大連接數,需要重啟數據庫
  • shutdown immediate; --關閉數據庫
  • startup; --重啟數據庫

v$process:

  • 這個視圖提供的信息,都是oracle服務進程的信息,沒有客戶端程序相關的信息

  • 服務進程分兩類,一是后台的,一是dedicate/shared server

  • pid, serial# 這是oracle分配的PID

  • spid 這才是操作系統的pid

  • program 這是服務進程對應的操作系統進程名

     select object_name,machine,s.sid,s.serial#
     	from v$locked_object l,dba_objects o ,v$session s
     	where l.object_id = o.object_id and l.session_id=s.sid; --查看數據庫表鎖死
     
     查詢鎖進程全部SQL
     select l.session_id sid, s.serial#, l.locked_mode, l.oracle_username,s.user#, l.os_user_name, 
        s.machine, s.terminal, a.sql_textfrom v$sqltext a, v$session s, v$locked_object l 
     	where l.session_id = s.sid and s.prev_sql_addr = a.address order by sid, s.serial#;
     
     select /*+ ORDERED */ sql_text from v$sqltext a where (a.hash_value,a.ADDRESS) in
     	( select decode(sql_hash_value,0,PREV_HASH_VALUE,sql_hash_value),
     	decode(sql_hash_value,0,PREV_SQL_ADDR,SQL_ADDRESS) from v$session b
     	where b.sid=&SID)
     	order by piece asc
     
     性能監控表
     	v$sql
     	v$sqlarea
     	v$sqltext
     	v$session
     
     Oracle數據庫表或數據刪除解決
     	https://blog.51cto.com/1197822/2157204
    

數據相關
--刪除指定用戶所有表的方法
select 'Drop table '||table_name||';'from all_tables where owner='要刪除的用戶名(注意要大寫)'; 
--查詢表和表字段描述
select t.* from user_col_comments t where t.table_name = 'T8_ALGORITHM_LOG';
--查詢表字段說明
select t.* from user_tab_columns t where t.table_name = 'T8_ALGORITHM_LOG'
--查詢表索引說明
select * from user_indexes t where t.table_name='T8_ALGORITHM_LOG';
--查詢表索引屬於那張表
select * from user_ind_columns t where t.table_name = 'T8_ALGORITHM_LOG';
--查詢表狀態
select * from user_tables t where t.table_name = 'T8_ALGORITHM_LOG';

DDL數據定義語言

表相關

  • --創建表
    create table TABLENAME (
    ID number not null ,
    DEALNO varchar2(50) ,
    contact_name varchar2(50) ,
    CONSTRAINT PK_TABLENAME_ID primary key(ID), --主鍵
    CONSTRAINT PK_TABLENAME_DEALNO UNIQUE (DEALNO)--創建表時創建唯一性約束
    );

    --刪除表
    drop table TABLENAME;
    --清空表
    truncat table TABLENAME;--DDL操作,不產生rollback,速度塊
    delete from TABLENAME;

    --修改表名
    alter table t8_forex_exchange rename to t8_forex_ex_deal_info
    --修改表字段類型
    alter table t8_forex_exchange modify (MSG_OPERATE_TYPE VARCHAR2(10))
    --修改字段長度時不生效可使用dba用戶修改
    UPDATE USER_TAB_COLUMNS SET DATA_TYPE='VARCHAR2', DATA_LENGTH=100 WHERE TABLE_NAME='T8_SYS_EXPRESSION';

    --增加表字段
    alter table t8_forex_exchange add (ftool_code VARCHAR2(32))
    --修改字段名
    alter table t8_forex_exchange rename column id to ids;

索引相關

--在字段上建立索引
create index INDEX_TABLENAME on TABLENAME (COLUMN1,COLUMN2);
--增加主鍵索引
alter table T8_FOREX_EXCHANGE add constraint T8_FOREX_EXCHANGE_PK primary key (ID);
--增加唯一索引
alter table T8_FOREX_EXCHANGE add constraint T8_FOREX_EXCHANGE_DEALNO unique (DEALNO);
--查詢表索引
select * from user_indexes t where t.table_name='TABLENAME';
--查詢表索引詳細信息
select * from user_ind_columns t where t.TABLENAME = 'T8_ALGORITHM_LOG';
--刪除索引
drop index index_name;
--修改索引名稱
ALTER TABLE TABLENAME RENAME CONSTRAINT SYS_C00421221 TO PK_PC59;
ALTER INDEX SYS_C00421221 RENAME TO PK_PC59;

創建用戶表空間

--創建表空間、用戶並賦予用戶權限
create tablespace tablespace 
	datafile '/u01/app/oracle/oradata/tablespace.dbf'
	size 200M reuse autoextend on next 16K maxsize unlimited extent management local 		autoallocate;

create user username
 	identified by "username"
  	default tablespace tablespace
  	temporary tablespace TEMP
  	profile DEFAULT;  

grant create user,drop user,alter user,create any view,
        select any table,delete any table,
        insert any table,update any table,
        drop any view ,exp_full_database,imp_full_database,
	create database link,
        connect,resource,create session to username;

--如果是12c數據庫還需要加上一條
alter user username QUOTA UNLIMITED ON tablespace

刪除用戶表空間

drop user username cascade; --刪除用戶以及關聯對象
drop tablespace tablespacename (including contents); --刪除表空間(非空表空間)

修改用戶密碼

alter user system identified by 123456; --修改用戶密碼
CREATE PUBLIC DATABASE LINK "MARKETDATA" CONNECT TO username IDENTIFIED BY "pwd"
	USING '(DESCRIPTION =(ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))) 
	(CONNECT_DATA =(SERVICE_NAME = ORCL)))'; --創建DB_LINK
drop public database link "MARKETDATABAK"; --刪除DB_LINK

存儲

索引

優化

in和exists

in 會先查詢子 再查詢外   exist 會先查外 再查子
select * fromm t8_bond_deal_info where id in (select ID from t8_bond_deal_info where id >1);
select * from t8_bond_deal_info bond where exists (select ID from t8_bond_deal_info where id >1 and id = bond.id);

SQL執行計划

explain plan for
	select * from sys_dict_item where dict like '%bond_market%'
select * from table(dbms_xplan.display)

數據庫SQL查詢統計

--查詢數據庫中執行最慢的50條SQL
select *
from (select sa.SQL_TEXT,
    sa.SQL_FULLTEXT,
    sa.EXECUTIONS "執行次數",
    round(sa.ELAPSED_TIME / 1000000, 2) "總執行時間",
    round(sa.ELAPSED_TIME / 1000000 / sa.EXECUTIONS, 2) "平均執行時間",
    sa.COMMAND_TYPE,
    sa.PARSING_USER_ID "用戶ID",
    u.username "用戶名",
    sa.HASH_VALUE
 from v$sqlarea sa
 left join all_users u
  on sa.PARSING_USER_ID = u.user_id
 where sa.EXECUTIONS > 0
 order by (sa.ELAPSED_TIME / sa.EXECUTIONS) desc)
where rownum <= 50;

--查詢數據庫中查詢次數最多的SQL
select *
from (select s.SQL_TEXT,
    s.EXECUTIONS "執行次數",
    u.username "用戶名",
    rank() over(order by EXECUTIONS desc) EXEC_RANK
 from v$sql s
 left join all_users u
  on u.USER_ID = s.PARSING_USER_ID
  where u.USERNAME = 'FMS_CLOUD'
  ) t
where exec_rank <= 100;

索引重建

版本區別

Oracle11gR2和Oracle12c不支持wm_concat解決

解決辦法:
1. 使用listagg
select listagg(ftool_code,',') within group (order by ftool_code) from t8_bond_deal_info group by 		ftool_code
select wm_concat(ftool_code) from t8_bond_deal_info group by ftool_code

2.
CREATE OR REPLACE TYPE WM_CONCAT_IMPL AS OBJECT
(
CURR_STR VARCHAR2(32767), 
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT WM_CONCAT_IMPL) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT WM_CONCAT_IMPL,
P1 IN VARCHAR2) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN WM_CONCAT_IMPL,
RETURNVALUE OUT VARCHAR2,
FLAGS IN NUMBER)
RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT WM_CONCAT_IMPL,
SCTX2 IN WM_CONCAT_IMPL) RETURN NUMBER
);

CREATE OR REPLACE TYPE BODY WM_CONCAT_IMPL
IS
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT WM_CONCAT_IMPL)
RETURN NUMBER
IS
BEGIN
SCTX := WM_CONCAT_IMPL(NULL) ;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT WM_CONCAT_IMPL,
P1 IN VARCHAR2)
RETURN NUMBER
IS
BEGIN
IF(CURR_STR IS NOT NULL) THEN
CURR_STR := CURR_STR || ',' || P1;
ELSE
CURR_STR := P1;
END IF;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN WM_CONCAT_IMPL,
RETURNVALUE OUT VARCHAR2,
FLAGS IN NUMBER)
RETURN NUMBER
IS
BEGIN
RETURNVALUE := CURR_STR ;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT WM_CONCAT_IMPL,
SCTX2 IN WM_CONCAT_IMPL)
RETURN NUMBER
IS
BEGIN
IF(SCTX2.CURR_STR IS NOT NULL) THEN
SELF.CURR_STR := SELF.CURR_STR || ',' || SCTX2.CURR_STR ;
END IF;
RETURN ODCICONST.SUCCESS;
END;
END;
	
CREATE OR REPLACE FUNCTION wm_concat(P1 VARCHAR2) RETURN VARCHAR2 AGGREGATE USING WM_CONCAT_IMPL ;	

create public synonym WM_CONCAT_IMPL for sys.WM_CONCAT_IMPL;
create public synonym wm_concat for sys.wm_concat;
grant execute on WM_CONCAT_IMPL to public;
grant execute on wm_concat to public;

使用問題

docker容器部署Oracle報錯sqlplus、impdp等操作未定義

export ORACLE_HOME=/u01/app/oracle-product/12.1.0/xe  
export PATH=$PATH:$ORACLE_HOME/bin  
export ORACLE_SID=xe

空表exp未導出

1、 deferred_segment_creation:是否延遲segment的創建,11g默認為true,即空表不創建segment,所以導出dmp沒有空表的信息。  
2、查看現有的狀態:show parameter deferred_segment_creation;  
3、修改狀態為false:alter system set  deferred_segment_creation=false;  
4、經過上面的步驟說明:以后建的空表都會創建segment,但是之前創建的空表不起作用,還是導不出信息。  
5、查詢用戶下所有的空表:  
    a、`select t.table_name from user_tables t where t.num_rows=0 or t.num_rows is null;`  
    b、`select t.table_name from all_tables t where t.owner='' and (t.num_rows =0 or t.num_rows is null);`  
6、給所有的空表分配segment:(分配空間)  
`select 'alter table ' || t.table_name || ' allocate extent' ||';' from user_tables t where t.num_rows=0 or t.num_rows is null; ` 
7、執行查詢結果。  

Oracle修改字符集編碼

shutdown immediate;  
startup mount;  
alter system enable restricted session;  
alter system set job_queue_processes=0;  
alter system set aq_tm_processes=0;  
alter database open;  
alter database character set internal_use ZHS16GBK;--AL32UTF8  
shutdown immediate;  
startup; 

imp ignore和fromuser/touser不生效

最終解決辦法是先創建需要的表空間,再調整表空間

數據庫切換表空間

--表
select 'alter table ' ||table_name|| ' move tablespace FMS_QHD_DATA;' table_name from dba_tables where owner='FMS_QHD'; 

--索引lob字段
select 'alter table ' ||ind.table_name|| ' move lob('||ind.index_name||') store as ( tablespace FMS_QHD_DATA);' from dba_indexes ind where ind.index_type = 'LOB' and owner = 'MFS_QHD'
或者
select 'alter table ' ||ind.table_name|| ' move lob('||ind.index_name||') store as ( tablespace FMS_QHD_DATA);' from dba_indexes ind
    left join user_tab_cols col on ind.TABLE_NAME=col.table_name where col.data_type like '%LOB%' and owner='FMS_QHD' ;

--索引表空間
select 'alter index ' ||index_name|| ' rebuild tablespace FMS_QHD_DATA;' index_name from dba_indexes where owner='FMS_QHD';

Oracle not available解決

sqlplus / as sysdba;
startup;

錯誤

ORA-28040:沒有匹配的驗證協議

  • 原因: oracle驅動不兼容,

  • 解決辦法: 修改ojdbc.jar。使用jdk1.8連接oracle12c需要ojdbc8.jar。注意classes12.jar也是oracle的低版本jdk1.1/jdk1.2的驅動,依賴需要去掉這個jar。也可以配置Oracle允許低版本訪問,在$ORACLE_HOME/${sid}/network/admin/sqlnet.ora中加入下面兩行,Oracle不需要重啟,但是重新連接會報錯用戶名密碼不對,還需要再次修改密碼

    SQLNET.ALLOWED_LOGON_VERSION_SERVER=8
    SQLNET.ALLOWED_LOGON_VERSION_CLIENT=8

ORA-00060:等待資源時檢測到死鎖

  • 原因:主外鍵關聯表設置級聯刪除,子表外鍵未加索引,並發情況刪除造成
  • 解決:1.子表外鍵加鎖(沒有死鎖情況也需要,否則會存在全表掃描) 2.刪除語句上加類鎖,在代碼處控制

Cannot get a connection, pool error Timeout waiting for idle object

  • 原因:數據庫連接滿了
  • 解決:修改數據庫允許的最大連接數

ORA-02019: connection description for remote database not found

  • 原因:dblink使用名錯誤
  • 解決:修改使用正確的dblink

ORA-00917: missing comma

  • 原因:sql語句錯誤,缺少逗號
  • 解決:

ORA-00924: 缺失 BY 關鍵字

  • 原因:排序字段寫道order by中間去了

IMPDP報錯

ORA-39001: invalid argument value
ORA-39000: bad dump file specification
ORA-31640: unable to open dump file "/u01/app/oracle/admin/xe/dpdump/t8_fund_info.dmp" for read
ORA-27041: unable to open file
Linux-x86_64 Error: 13: Permission denied
Additional information: 9
原因:dmp文件權限問題
解決:chown -R oracle:dba /u01/app/oracle/admin/xe/dpdump/expdat.dmp 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM