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小於100000Sample=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\'\"
--LinuxEXCLUDE=SEQUENCE,VIEW
--過濾所有的SEQUENCE,VIEWEXCLUDE=TABLE:"IN ('EMP','DEPT')"
--過濾表對象EMP,DEPTEXCLUDE=SEQUENCE,VIEW,TABLE:"IN ('EMP','DEPT')"
--過濾所有的SEQUENCE,VIEW以及表對象EMP,DEPTEXCLUDE=INDEX:"= 'INDX_NAME'"
--過濾指定的索引對象INDX_NAMEINCLUDE=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
導入切換用戶,從多個用戶切換到touserREMAP_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; --修改用戶密碼
創建/刪除DB_LINK
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