OCA/OCP(Oracle Certified Associate/Profesional)

感谢公司资助的Oracle培训,我自己也摸索学习了其中一些东西,整理了一篇小文章,希望能帮到大家。

 

目录

12c, 18c, 19c

OCA/OCP 12c 认证

Oracle体系结构

Oracle逻辑结构

Oracle物理结构

Oracle内存结构

Oracle备份(Backup)与恢复(Recovery)方案

Oracle安装

Some OCA/OCP(071) Testing SQL

Some DBA SQL

Generate AWR report

归档日志

控制文件


12c, 18c, 19c

12c版本号是12.1.0.2.0。

18c版本号是12.2.0.2,19c版本号是12.2.0.3,这两个年度版本仍然处于 12c 的发布序列中, 19c 属于 12c 体系的最后一个版本

 

OCA/OCP 12c 认证

OCA 12c 认证包括 071, 062 两门认证考试

OCP 12c 认证包括 071, 062 & 063三门认证考试

071: Oracle Database SQL Exam

062: Oracle Database Installation and Adminstration

063: Oracle Database Advanced Adminstration

以下是知识点分类总结+自己的实操体会

(后续会从OneNote整理出来)

Oracle体系结构

Oracle12c体系结构:

Oracle11g体系结构:

 

Oracle逻辑结构

 

Oracle物理结构

 

Oracle内存结构

ASM(Automatic Storage Management, 自动存储管理)

 

Oracle备份(Backup)与恢复(Recovery)方案

RMAN

Oracle Secure Backup (OSB)  

与RMAN一起,Oracle Secure Backup(OSB)将从FRA中提取RMAN备份,并将其复制到磁带设备或云存储中,以防止数据中心发生灾难性故障而丢失数据。OSB还在OS级别上提供了对RMAN的扩展,以备份Linux服务器以及诸如NAS设备之类的任何附加存储。

Oracle Data Guard

 

Oracle安装

Linux版已装过; Mac版用了最快的Docker方法, 起了个实例, 以下是Mac, Windows类似.(您可以先下载安装Mac/Windows Docker Desktop)

bethxfchen:~ cxf$ docker --version

Docker version 20.10.0, build 7287ab3

bethxfchen:~ cxf$ docker info

Client:

 Context:    default

 Debug Mode: false

 Plugins:

  app: Docker App (Docker Inc., v0.9.1-beta3)

  buildx: Build with BuildKit (Docker Inc., v0.4.2-docker)

  scan: Docker Scan (Docker Inc., v0.5.0)

Server:

 Containers: 0

  Running: 0

  Paused: 0

  Stopped: 0

 Images: 0

 Server Version: 20.10.0

 Storage Driver: overlay2

  Backing Filesystem: extfs

  Supports d_type: true

  Native Overlay Diff: true

 Logging Driver: json-file

 Cgroup Driver: cgroupfs

 Cgroup Version: 1

 Plugins:

  Volume: local

  Network: bridge host ipvlan macvlan null overlay

  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog

 Swarm: inactive

 Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc

 Default Runtime: runc

 Init Binary: docker-init

 containerd version: 269548fa27e0089a8b8278fc4fc781d7f65a939b

 runc version: ff819c7e9184c13b7c2607fe6c30ae19403a7aff

 init version: de40ad0

 Security Options:

  seccomp

   Profile: default

 Kernel Version: 4.19.121-linuxkit

 Operating System: Docker Desktop

 OSType: linux

 Architecture: x86_64

 CPUs: 1

 Total Memory: 1.943GiB

 Name: docker-desktop

 ID: J7YZ:4YZP:B2NL:KWV5:Q7IC:GPTY:LLVA:CTUB:IGKW:AFCO:7MC3:CBNV

 Docker Root Dir: /var/lib/docker

 Debug Mode: true

  File Descriptors: 40

  Goroutines: 45

  System Time: 2020-12-16T14:45:20.4562986Z

  EventsListeners: 3

 HTTP Proxy: gateway.docker.internal:3128

 HTTPS Proxy: gateway.docker.internal:3129

 Registry: https://index.docker.io/v1/

 Labels:

 Experimental: false

 Insecure Registries:

  127.0.0.0/8

 Live Restore Enabled: false

 Product License: Community Engine

bethxfchen:~ cxf$ docker images

REPOSITORY   TAG       IMAGE ID   CREATED   SIZE

bethxfchen:~ cxf$ docker login

Authenticating with existing credentials...

Login Succeeded

bethxfchen:~ cxf$ docker pull store/oracle/database-enterprise:12.2.0.1

12.2.0.1: Pulling from store/oracle/database-enterprise

4ce27fe12c04: Pull complete 

9d3556e8e792: Pull complete 

fc60a1a28025: Pull complete 

0c32e4ed872e: Pull complete 

b465d9b6e399: Pull complete 

Digest: sha256:40760ac70dba2c4c70d0c542e42e082e8b04d9040d91688d63f728af764a2f5d

Status: Downloaded newer image for store/oracle/database-enterprise:12.2.0.1

docker.io/store/oracle/database-enterprise:12.2.0.1

bethxfchen:~ cxf$ docker images

REPOSITORY                         TAG        IMAGE ID       CREATED       SIZE

store/oracle/database-enterprise   12.2.0.1   12a359cd0528   3 years ago   3.44GB

bethxfchen:~ cxf$ docker run -d -it --name Oracle-DB -p 1521:1521/tcp store/oracle/database-enterprise:12.2.0.1

2fae09ee962d409fc41cdba57b2bb706bd1d7ab385b8668315356e7afd00cdef

bethxfchen:~ cxf$ docker ps

CONTAINER ID   IMAGE                                       COMMAND                  CREATED          STATUS                             PORTS                              NAMES

2fae09ee962d   store/oracle/database-enterprise:12.2.0.1   "/bin/sh -c '/bin/ba…"   17 seconds ago   Up 16 seconds (health: starting)   0.0.0.0:1521->1521/tcp, 5500/tcp   Oracle-DB

通过SQL Developer连接:

连接成功:

因为题目很多是会用到HR, 但Docker装的Oracle里默认没有Sample HR Schema, 所以docker exec -it Oracle-DB /bin/bash进入到Docker装的oracle env, sqlplus / as sysdba进入到SQL env后:

SQL> @?/demo/schema/human_resources/hr_main.sql就可以生成hr schema相关objects.

注意: 因为遇到了ORA-20000: Schema "HR" does not exist or insufficient privileges的问题,所以

alter session set "_ORACLE_SCRIPT"=true;

create user hr identified by hr;

drop user hr cascade;

@?/demo/schema/human_resources/hr_main.sql;

可以成功创建HR Sample Schema。

SQL> alter session set "_ORACLE_SCRIPT"=true; 

Session altered.

SQL> create user hr identified by hr;

User created.

SQL> drop user hr cascade;

User dropped.

SQL> @?/demo/schema/human_resources/hr_main.sql

specify password for HR as parameter 1:
Enter value for 1: hr

specify default tablespeace for HR as parameter 2:
Enter value for 2: users

specify temporary tablespace for HR as parameter 3:
Enter value for 3: temp

specify log path as parameter 4:
Enter value for 4: $ORACLE_HOME/demo/schema/log/


PL/SQL procedure successfully completed.

验证如下:

Some OCA/OCP(071) Testing SQL

--------------------------------------------------------------分组函数 start---------------------------------------------------------
--count
select department_id from employees; --总共107行,第79行的department_id为null
select count(*) from employees; --107
--count(expr)返回expr非空的记录总数。
select count(department_id) from employees; --106
--count(distinct expr)返回expr非空且不重复的记录总数。
select count(distinct department_id) from employees; --11

select count(distinct last_name) from employees; --102

select distinct department_id from employees; --12,包括null值
select distinct job_id from employees; --19
select distinct job_id, department_id from employees; --20
select distinct department_id, job_id from employees;  --20

--nvl
select commission_pct from employees;
--组函数忽略空值。
select avg(commission_pct) from employees; --0.2228571428571428571428571428571428571429
--在组函数中使用NVL函数, NVL函数使分组函数无法忽略空值。
select avg(nvl(commission_pct, 0)) from employees; --0.072897196261682242990654205607476635514

--avg, sum可以对数值型数据使用;min, max可以对任意数据类型数据使用。
select min(hire_date), max(hire_date) from employees; 
select min(first_name) from employees; --Adam

--在select列表中所有未包含在组函数中的列都应该包含在group by子句中。
select department_id, avg(salary) from employees group by department_id;
--包含在group by子句中的列不必包含在select列表中。
select avg(salary) from employees group by department_id;
--使用多个列分组,在group by子句中包含多个列。
select department_id, job_id,sum(salary) from employees group by department_id, job_id;
--不能在where子句中使用组函数。可以在having子句中使用组函数。
--比如下面这句就不对:
select department_id, avg(salary) from employees where avg(salary) >8000 group by department_id;
--过滤分组:使用having。
select job_id, sum(salary) payroll from employees where job_id not like '%REP%' group by job_id having sum(salary)>13000 order by sum(salary);
--嵌套组函数
select max(avg(salary)) from employees group by department_id;
select max(salary) from employees group by salary; --multiple values
select avg(max(salary)) from employees group by salary; --7067.379310344827586206896551724137931034
select department_id, sum(salary) from employees where hire_date<'01-JAN-19' group by department_id;
select department_id, sum(salary) from employees group by department_id;
select department_id, max(sum(salary)) from employees group by department_id; --ORA-00937: not a single-group group function
select department_id, max(salary) from employees group by department_id;
select department_id, avg(salary) from employees group by department_id; 
select department_id, max(avg(salary)) from employees group by department_id; --ORA-00937: not a single-group group function
select department_id, avg(max(salary)) from employees group by department_id, salary; --ORA-00937: not a single-group group function
select department_id, avg(max(salary)) from employees group by department_id having hire_date<'01-JAN-19'; --ORA-00937: not a single-group group function

--题目中以下四个语句中错的是第一句
--ORA-00934: group function is not allowed here
select department_id, count(*) from employees where department_id <> 90 and count(*) >=3 group by department_id;
--以下三句是可以的,where是对分组前进行过滤,having是对分组后进行过滤,group by和having顺序没有限制
select department_id, count(*) from employees where department_id <> 90 having count(*) >=3 group by department_id;
select department_id, count(*) from employees having department_id <> 90 and count(*) >= 3 group by department_id;
select department_id, count(*) from employees where department_id <> 90 group by department_id having count(*) >=3;

--------------------------------------------------------------分组数据 end---------------------------------------------------------

--------------------------------------------------------------连接 start---------------------------------------------------------

--(+)外连接的符号

select * from employees e, departments d where e.department_id = d.department_id;
--SQL:1999语法连接
select * from employees e join departments d on e.department_id = d.department_id;
--增加连接条件
select * from employees e join departments d on e.department_id = d.department_id and e.manager_id = 149;
select * from employees e join departments d on (e.department_id = d.department_id) and e.manager_id = 149;
select * from employees e join departments d on e.department_id = d.department_id where e.manager_id = 149;
--或
select * from employees e join departments d using (department_id); 
select * from employees e join departments d using (department_id) and e.manager_id = 149; --ORA-00933: SQL command not properly ended



-- full/left/right <outer> join; natural join会以两个表中具有相同名字的列为条件创建等值连接,如果只是列名相同而数据类型不同,则会产生错误;cross join叉集就是笛卡尔集。
select count(*) from "123"; --5
select count(*) from employees; --107
select * from "123", employees; --535行的数据
select count(*) from "123", employees; --535

--------------------------------------------------------------连接 end---------------------------------------------------------

--------------------------- --------------------------------- NVL & NVL2 & NULLIF & coalesce start ----------------------------------------------------------------------------------------------------
--NVL & NVL2 & NULLIF & coalesce:
--(1)NVL(expr1,expr2),将空值替换成一个值,若expr1为null, 返回expr2; 不为null,返回expr1。  
--    数据类型可以是日期,数字,字符。
--    数据类型必须匹配:
--    nvl(commision,0)
--    nvl(hiredate,'01-JAN-87')
--    nvl(job_id,'no manager') nvl(to_char(job_id),'no manager')
--    nvl能够转换任何数据类型,但是转换的数据类型返回值必须是nvl(expr1,expr2)第一个参数expr的类型。如:date,number, varchar2 or char
select NVL(commission_pct, 0) from employees;
select NVL('DATE', SYSDATE) from dual;
select NVL('DATE', 200) from (select null as "DATE" from dual);
--(2)NVL2 (expr1, expr2, expr3),通俗的理解就是一个值非不非空都替换,非空是一个,空是另一个;若expr1不为NULL,返回expr2 ;为NULL,返回expr3。注意:expr2 和expr3 类型不同的话,expr3 会转换为expr2 的类型
SELECT NVL2(commission_pct, commission_pct*100, 0) FROM employees;
select hire_date from employees;
SELECT EMPLOYEE_ID, NVL2(HIRE_DATE, SYSDATE - HIRE_DATE, SYSDATE) from employees;
select EMPLOYEE_ID, NVL2(EMPLOYEE_ID, EMPLOYEE_ID*.25, "Not Available") from employees; --ORA-00904: "Not Available": invalid identifier
--(3)NULLIF (expr1, expr2),通俗的理解就是对比两个值相不相等;expr1和expr2相等时,返回结果null, 不相等时返回expr1
select NULLIF(length(first_name),length(last_name)) result from employees;
--(4)coalesce用途
select * from employees; --总共107行,第79行的department_id为null
--coalesce用途1:将控制替换成其他值;
select coalesce(department_id,1) from employees; --总共107行,第79行的department_id为1
--coalesce用途2:返回第一个非空值
select coalesce(commission_pct,salary,10) from employees;
select coalesce('DATE', SYSDATE) from dual; --ORA-00932: inconsistent datatypes: expected CHAR got DATE
--------------------------- --------------------------------- NVL & NVL2 & NULLIF & coalesce end ----------------------------------------------------------------------------------------------------


--------------------------- --------------------------------- 日期/时间 start ----------------------------------------------------------------------------------------------------
--日期函数 默认的日期格式是DD-MON-RR
select months_between('01-SEP-95','11-JAN-94') from dual; -- 19.67741935483870967741935483870967741935
select add_months(sysdate,-2) from dual;
select next_day('19-DEC-2020', 'FRIDAY') from dual; -- 25-DEC-20
select last_day(sysdate) from dual;
select last_day(to_date('1992-10-09','yyyy-mm-dd')) from dual;
select round(sysdate, 'MONTH') from dual; -- 01-JAN-21
select trunc(sysdate, 'MONTH') from dual; -- 01-DEC-20

--timestamp & timezone & date
select current_timestamp from dual; --20-DEC-20 10.50.19.189027000 PM ASIA/SHANGHAI
select sessiontimezone from dual;   --Asia/Shanghai
select LOCALTIMESTAMP from dual;    --28-DEC-20 05.28.23.897737000 PM

select SYSTIMESTAMP from dual;      --28-DEC-20 09.28.32.197928000 AM GMT
select dbtimezone from dual;        --+00:00


select current_date from dual;      --20-DEC-20
select SYSDATE from dual;           --20-DEC-20

alter session set NLS_DATE_FORMAT='DD-MON-YYYY HH24:MI:SS';
select current_date from dual;  --05-JAN-2021 23:10:02
select SYSDATE from dual; --05-JAN-2021 15:10:29


select DATE'2017-08-01' from dual;  --01-AUG-17
SELECT (SYSDATE-DATE'2019-01-01')/1 FROM DUAL;
SELECT SYSDATE-DATE'2019-01-01'-1 FROM DUAL;
SELECT SYSDATE-1-DATE'2019-01-01' FROM DUAL; --SYSDATE-1查询结果是20-DEC-20

select round(sysdate - to_date('01-JAN-2019')) from dual; --739
select round(sysdate - to_date('01/JANUARY/2019')) from dual; --739
select round(sysdate - '01-JAN-2019') from dual; --ORA-01722: invalid number
select trunc(sysdate - to_date('01-JAN-2019')) from dual; --739
select trunc(sysdate) from dual; --09-JAN-21
select round(sysdate) from dual; --09-JAN-21


alter session set nls_date_format='DD-MM-YYYY';
select to_date('29-10-2019') + INTERVAL '2' MONTH from dual; --29-12-2019
select to_date('29-10-2019') + INTERVAL '2' MONTH + INTERVAL '5' DAY from dual; --03-01-2020
select INTERVAL '120' SECOND from dual; --+00 00:02:00.000000
select to_date('29-10-2019') + INTERVAL '2' MONTH + INTERVAL '5' DAY - INTERVAL '120' SECOND from dual; --02-01-2020
select to_char(to_date('29-10-2019') + INTERVAL '2' MONTH + INTERVAL '5' DAY - INTERVAL '120' SECOND, 'DD-MON-YYYY') as "date" from dual; --03-01-2020相当于03-01-2020 00:00:00,减去120秒也是02-01-2020

select to_char(INTERVAL '800' SECOND, 'HH24:MM') from dual; --+00 00:13:20.000000
select to_date(INTERVAL '800' SECOND, 'HH24:MM') from dual; --ORA-01843: not a valid month
select to_number(INTERVAL '800' SECOND, 'HH24:MM') from dual; --ORA-01481: invalid number format model
select to_date(to_number(INTERVAL '800' SECOND, 'HH24:MM')) from dual; --ORA-01481: invalid number format model
select to_number(to_date(INTERVAL '800' SECOND, 'HH24:MM')) from dual; --ORA-01843: not a valid month

select to_date('2019-DEC-25 15:30', 'YYYY-MON-DD HH24:MI', 'NLS_DATE_LANGUAGE = AMERICAN') from dual; --25-DEC-19
select to_char(to_date('2019-DEC-25 15:30', 'YYYY-MON-DD HH24:MI')) from dual; --25-DEC-19

select salary from employees where hire_date > '01-03-2019'; --日期格式有问题,ORA-01843: not a valid month
select salary from employees where hire_date < '01-march-2019';

select SYSTIMESTAMP from dual; --02-JAN-21 02.05.13.650093000 AM GMT
select SYSTIMESTAMP + INTERVAL '0 12' DAY TO HOUR from dual; --02-JAN-21 02.05.24.311813000 PM GMT

--Set the time zone at database level (alter database)
select dbtimezone from dual; --+00:00
alter database set time_zone='Europe/London'; --OR alter database set time_zone='-08:00';
----restart the database: Shutdown immediate; => startup
SELECT dbtimezone FROM DUAL; --Europe/London

--Set the time zone at session level (alter session)
--alter session set time_zone=local;
--alter session set time_zone=dbtimezone;
alter session set time_zone='Asia/Hong_Kong'; --OR alter session set time_zone='+08:00';
select sessiontimezone from dual; --Asia/Hong_Kong
--------------------------- --------------------------------- 日期/时间 end ----------------------------------------------------------------------------------------------------

--------------------------- --------------------------------- 相关/关联子查询 start ----------------------------------------------------------------------------------------------------

create table orders(
    customer_name varchar2(8),
    customer_id number
);
create table customers(
    customer_id number,
    cust_last_name varchar2(8)
);

insert into orders(customer_name, customer_id) values('o1', 10);
insert into orders(customer_name, customer_id) values('o2', 20);
insert into orders(customer_name, customer_id) values('o3', 30);
insert into orders(customer_name, customer_id) values('o4', 40);
commit;
select * from orders;
insert into customers(cust_last_name, customer_id) values('c1', 10);
insert into customers(cust_last_name, customer_id) values('c2', 20);
insert into customers(cust_last_name, customer_id) values('c3', 30);
commit;
select * from customers;
--All existing rows in the ORDERS table are updated. The subquery is executed for every updated row in the ORDERS table.
update orders o set customer_name = (select cust_last_name from customers where customer_id = o.customer_id); --4 rows updated.
select * from orders; --customer_name四行的结果分别是c1 c2 c3 (null)


create table customers_history as select * from customers;
select * from customers_history;
insert into customers_history values(50, 'c5'); --customers_history四行,customers三行
commit;
delete from customers c where exists (select 'dummy' from customers_history where customer_id=c.customer_id); --3 rows deleted. customers三行被删掉了
rollback;
select * from customers;
select * from customers_history;
insert into customers values(60, 'c6'); --customers_history四行,customers三行
commit;
--相关子查询,只会将父表中匹配条件的行记录删除,保留其他行。
--The subquery is executed for every row in the CUSTOMERS table.
delete from customers c where exists (select 'dummy' from customers_history where customer_id=c.customer_id); --3 rows deleted. customers三行被删掉了,剩下60,c6一行

--------------------------- --------------------------------- 相关/关联子查询 end ----------------------------------------------------------------------------------------------------

--------------------------- --------------------------------- 事务 start ----------------------------------------------------------------------------------------------------

insert into "123" values('c');
savepoint a;
delete from "123";
rollback to savepoint a;
rollback;

--测试transaction
insert into "123" values('b');
select xid, status from v$transaction; --0F000800E8010000	ACTIVE
truncate table "123";
select * from "123"; --truncated, no data.
select xid, status from v$transaction; --no data.

insert into "123" values('b'); 
select xid, status from v$transaction; --13001B00D2010000	ACTIVE
insert into "123" values('d'); 
select xid, status from v$transaction; --13001B00D2010000	ACTIVE
rollback;
select xid, status from v$transaction; --no data.

insert into "123" values('a'); 
select xid, status from v$transaction; --0E000600D6010000	ACTIVE
insert into "123" values('b'); 
select xid, status from v$transaction; --0E000600D6010000	ACTIVE
commit;
select xid, status from v$transaction; --no data.

insert into "123" values('e');
select xid, status from v$transaction;  --13001900CF010000	ACTIVE
insert into "123" values('e', 'f');  --SQL Error: ORA-00913: too many values
select xid, status from v$transaction; --13001900CF010000	ACTIVE
insert into "123" values('f');
select xid, status from v$transaction; --13001900CF010000	ACTIVE
delete from "123" where test='a';
select xid, status from v$transaction; --13001900CF010000	ACTIVE

create table test_transaction as select * from "123"; 
select xid, status from v$transaction; --no data.
select * from "123"; -- e, f were inserted. a was deleted.

insert into "123" values('a'); 
select xid, status from v$transaction; --0F000F00EC010000	ACTIVE
select * from "123" for update;
create table test_transaction1 as select * from "123"; 
select xid, status from v$transaction; --no data

insert into "123" values('a'); 
select xid, status from v$transaction; --0A000F00DC010000	ACTIVE
create index test_index on "123" (test);
select xid, status from v$transaction; --no data
create table test_table1 (
    column1 varchar2(2),
    column2 number
);
select xid, status from v$transaction; --no data
--------------------------------------------------------------事务 end---------------------------------------------------------

--------------------------------------------------------------转义 start---------------------------------------------------------
--escape
select 'The first_name is ' || first_name || '' from employees; --The first_name is Ellen
select 'The first_name is ''' || first_name || '''' from employees; --The first_name is 'Ellen'
select 'The first_name is ''' || first_name || ''' from employees; --ORA-01756: quoted string not properly terminated
select 'The first_name is '' || first_name || '' from employees; --ORA-01756: quoted string not properly terminated
select 'The first_name is \'' || first_name || '\'' from employees; --ORA-00911: invalid character *Cause: The identifier name started with an ASCII character other than a letter or a number. After the first character of the identifier name, ASCII characters are allowed including "$", "#" and "_".
--The most simple and most used way to escape in strings    
SELECT 'test single quote''' from dual; --test single quote'
SELECT '''test single quote''' from dual; --'test single quote'

--q'!!'; q'[]'; q'{}'; q'()'; q'<>'五种符号都可以
select q'!Hello! We're ready!' from dual; --Hello! We are ready
select q'[Hello! We're ready]' from dual; --Hello! We are ready

--下面这两种都不行
--select '[Hello! We\'re ready]' escape '\' from dual; --ORA-00923: FROM keyword not found where expected
select "Hello! We're ready" from dual; --ORA-00904: "Hello! We're ready": invalid identifier
--------------------------------------------------------------转义 end---------------------------------------------------------

--------------------------------------------------------------Merge start---------------------------------------------------------
--Merge:
--	语法如下:
--	MERGE INTO table_name alias1 
--	USING (table|view|sub_query) alias2
--	ON (join condition) 
--	WHEN MATCHED THEN 
--	    UPDATE table_name 
--	    SET col1 = col_val1, 
--	        col2     = col2_val 
--	WHEN NOT MATCHED THEN 
--	    INSERT (column_list) VALUES (column_values); 
--	UPDATE子句后面可以跟DELETE子句来去除一些不需要的行
--  UPDATE或INSERT子句是可选的
--------------------------------------------------------------Merge end---------------------------------------------------------

--------------------------------------------------------------All set operators(UNION, UNION ALL, INTERSECT and MINUS) start---------------------------------------------------------
--Union/union all:
--	The first column in the first select of the compound query with the union operator issued by default to sort output in the absence of an order by clause.
--	Only column names from the first select statement in the compound query are recognized. 
--	All set operators(UNION, UNION ALL, INTERSECT and MINUS) are valid on columns of all data types. 
--	The data type of each column returned by the second query must be implicitly convertible to the data type of the corresponding column returned by the first query
--	The number, but not names of columns must be identical for all SELECT statements in the query
--	UNION ALL
--	NULLS are not ignored during duplicate checking
--    The number of columns selected in each SELECT statement must be identical 

--INTERSECT
--  returns rows common to both sides of the compound query.
SELECT 1 AS id, 'John' AS first_name, NULL AS commission FROM dual INTERSECT
SELECT 1,'John', null FROM dual ORDER BY 3;
--	What is returned upon execution?[
--	D) 1 ROW
--	(1)Column names in each SELECT in the compound query can be different.
--  (2)The number of columns and data types must be identical for all SELECT statements in the query

--INTERSECT does not ignore NULLs
SELECT COL1 FROM (SELECT 1 COL1 FROM DUAL UNION ALL
                    SELECT 1 FROM DUAL UNION ALL
                    SELECT NULL FROM DUAL)
INTERSECT
SELECT COL2 FROM (SELECT NULL COL2 FROM DUAL UNION ALL
                    SELECT 1 FROM DUAL UNION ALL
                    SELECT NULL FROM DUAL)
ORDER BY 1 NULLS FIRST;
--------------------------------------------------------------All set operators(UNION, UNION ALL, INTERSECT and MINUS) end---------------------------------------------------------

--------------------------------------------------------------系统视图 start---------------------------------------------------------
select * from session_privs;

select * from user_synonyms;

select * from user_objects;

select * from dictionary;
--------------------------- --------------------------------- 系统视图 end ----------------------------------------------------------

--------------------------------------------------------------其他 start---------------------------------------------------------
--order by
--(1)多个列排序 order by department_id, salary desc: 是在第一列department_id asc的前提下, 第一列相等时,才按照第二列salary desc
select last_name, department_id, salary from employees order by department_id, salary desc;
--(2)order by后可以用别名,可以按照别名排序;Table aliases can improve performance.
select last_name, department_id, salary s from employees order by s desc;
select department_id AS "Department", avg(salary) AverageSalary, max(salary) AS "Max Salary" from employees where salary>=12000 group by department_id order by AverageSalary;
--(3)group by后不能用别名
select department_id AS "Department", avg(salary) AverageSalary, max(salary) AS "Max Salary" from employees where salary>=12000 group by "Department" order by AverageSalary;
--(4)order by后如果加1、2等数字看第一个select语句的column顺序
--(5)多个select时,order by放最后select
--(6)order by排序时是大小写敏感的,order by XXX默认asc先按大写A到Z,再小写a到z。
update employees set first_name=lower(first_name) where first_name like 'E%';
update employees set first_name=lower(first_name) where first_name like 'S%';
select first_name from employees order by first_name;

--where里不要用别名
select last_name, 12*salary as annual_salary from employees where 12*salary > 100000 order by annual_salary;
--下面两种都报错:ORA-00904: "ANNUAL_SALARY": invalid identifier
select last_name, 12*salary as annual_salary from employees where annual_salary > 100000 order by annual_salary;
select last_name, 12*salary as annual_salary from employees where annual_salary > 100000 order by 12*salary;


--字符数字控制函数
SELECT concat('Hello','World') FROM dual;
--0和1都是表示截取的开始位置为第一个字符; 以及length
SELECT substr('HelloWorld',0,5) FROM dual; 
SELECT substr('HelloWorld',1,5) FROM dual;
SELECT instr('HelloWorld','H') FROM dual; -- 1
SELECT length('HelloWorld') FROM dual;
SELECT lpad(salary, 10, '*') FROM employees;
SELECT rpad(salary, 10, '*') FROM employees;
SELECT upper(last_name) FROM employees; -- or lower, initcap
--round四舍五入&trunc截断,expr2默认是0,可正可负,0是个位数,以此为分界点,数字往左是负数
select round(45.923, -1) from dual;
select trunc(45.923, -2) from dual;
--mod取余


--数据类型转换 0和9均可代表数字,L是本地货币符号,逗号是千位符
SELECT to_char(salary,'$99,999,00') FROM employees;
SELECT to_char(salary,'L00,000.00') FROM employees;
SELECT to_char(hire_date,'MON DD, YYYY') FROM employees; -- JUN 17, 2003;如果写MONTH是月份全拼
--注意是HH24:MI:SS
SELECT to_char(sysdate,'HH24:MI:SS AM, DAY') FROM dual; -- 12:11:12 PM, FRIDAY   


select salary from employees where salary between '4000' and '8000'; --隐式转换


--包含空值的数学表达式的值都为空值
select last_name || 12*salary*commission_pct from employees where commission_pct is null;

--注意可以这么用
SELECT DISTINCT * FROM employees WHERE first_name IS NOT NULL;


--条件表达式
--(1)case是IF-THEN-ELSE逻辑
select last_name, job_id, salary, 
       case job_id when 'IT_PROG' then 1.10*salary 
                   when 'ST_CLERK' then 1.15*salary 
                   when 'SA_REP' then 1.20*salary 
       else salary end "revised_salary" 
from employees;
--(2)decode是IF-THEN-ELSE逻辑:decode(col|expr, search1, result1[,search2, result1,...,][,default])



--以下两个查询返回相同的结果:all rows for employees whose salary is greater than the average salary in their department
select * from employees e1 where salary > (select avg(salary) from employees e2 where e1.department_id=e2.department_id);
--over(partition by XXX)
select * from (select e.*, avg(salary) over(partition by department_id) avg_sal from employees e) where salary > avg_sal;


drop table "123";
create table "123" (
    test varchar2(10)
); --create时不加引号和单引号都不可以
insert into "123" values('a');
insert into "123" values('b');
commit;
select * from 123; --不加引号和单引号都不可以
select * from '123'; --不加引号和单引号都不可以
select * from \'123\'; --加转义符号也不可以
select * from "123";


delete from "123" where test='a';
delete "123" where test='b';
delete from "123";
truncate table "123";


create table "123" (
    testNum number(6,2) NOT NULL
); 
desc "123";
INSERT INTO "123" VALUES (-.9); --0.9
INSERT INTO  "123" VALUES (0.999); --1
commit;
create table "new_123" as select * from "123";
desc "new_123"; -- 新表也有NOT NULL constraint

INSERT INTO "123" VALUES (-.9); --0.9
INSERT INTO  "123" VALUES (0.999); --1
INSERT INTO  "123" VALUES (0.551);
INSERT INTO  "123" VALUES (-10);

create or replace view view_123 as select * from "123";
create or replace view view_123_b as select * from "123" where test='b';
select * from view_123;
select * from view_123_b;
--purge
drop table "123" purge; --table和所有的views都会删除,不能rollback


--accessible to all users: PUBLIC
CREATE PUBLIC SYNONYM emp FOR hcm.Employee_records;


--Which two are true about external tables that use the ORACLE_DATAPUMP access driver?
--A)When creating an external table, data can be selected from another external table or from a
--table whose rows are stored in database blocks
--B) Creating an external table creates a dump file that can be used by an external table in the
--same or a different database


--测试返回结果是否相同
select emp.* from employees emp
join employees mgr
on emp.manager_id=mgr.employee_id
and emp.department_id <> mgr.department_id; --18 rows

select emp.* from employees emp
right join employees mgr
on emp.manager_id=mgr.employee_id
and emp.department_id <> mgr.department_id
where emp.employee_id is not null; --18 rows

select emp.* from employees emp
left join employees mgr
on emp.manager_id=mgr.employee_id
and emp.department_id <> mgr.department_id; --107 rows

select emp.* from employees emp where manager_id not in (select mgr.employee_id from employees mgr where emp.manager_id<>mgr.manager_id); --15 rows

select mgr.* from employees mgr where manager_id not in (select emp.employee_id from employees emp where emp.manager_id<>mgr.manager_id); --15 rows
--------------------------------------------------------------其他 end---------------------------------------------------------


Some DBA SQL

--oracle lock

SELECT c.owner
  ,c.object_name
  ,c.object_type
  ,b.sid
  ,b.serial#
  ,b.status
  ,b.osuser
  ,b.machine
FROM v$locked_object a 
    ,v$session b
    ,dba_objects c
WHERE b.sid = a.session_id
AND a.object_id = c.object_id;

--oracle long query

SELECT s.username,
       sl.sid,
       sq.executions,
       sl.last_update_time,
       sl.sql_id,
       sl.sql_hash_value,
       opname,
       target,
       elapsed_seconds,
       time_remaining,
       sq.sql_fulltext
  FROM v$session_longops sl
 INNER JOIN v$sql sq ON sq.sql_id = sl.sql_id
 INNER JOIN v$session s ON sl.SID = s.SID AND sl.serial# = s.serial#
 WHERE time_remaining > 0;

--oracle active session

SELECT s.sid sid
,sa.sql_id
,s.serial# serial_id
,s.status session_status
,s.username oracle_username
,s.osuser os_username
,p.spid os_pid
,s.machine session_machine
,s.program session_program
,s.client_info
,s.sql_exec_start
,substr(sa.sql_text, 1, 1024) current_sql
FROM gv$process p, gv$session s, gv$sqlarea sa
WHERE p.addr(+) = s.paddr
AND s.sql_address = sa.address(+)
AND s.sql_hash_value = sa.hash_value(+)
AND s.username IS NOT NULL
AND s.status = 'ACTIVE'
ORDER BY sid;

查询结果局部截图:

--oracle tablespace

SELECT /* + RULE */  df.tablespace_name "Tablespace",
       df.bytes / (1024 * 1024) "Size (MB)",
       SUM(fs.bytes) / (1024 * 1024) "Free (MB)",
       Nvl(Round(SUM(fs.bytes) * 100 / df.bytes),1) "% Free",
       Round((df.bytes - SUM(fs.bytes)) * 100 / df.bytes) "% Used"
  FROM dba_free_space fs,
       (SELECT tablespace_name,SUM(bytes) bytes
          FROM dba_data_files
         GROUP BY tablespace_name) df
 WHERE fs.tablespace_name (+)  = df.tablespace_name
 GROUP BY df.tablespace_name,df.bytes
UNION ALL
SELECT /* + RULE */ df.tablespace_name tspace,
       fs.bytes / (1024 * 1024),
       SUM(df.bytes_free) / (1024 * 1024),
       Nvl(Round((SUM(fs.bytes) - df.bytes_used) * 100 / fs.bytes), 1),
       Round((SUM(fs.bytes) - df.bytes_free) * 100 / fs.bytes)
  FROM dba_temp_files fs,
       (SELECT tablespace_name,bytes_free,bytes_used
          FROM v$temp_space_header
         GROUP BY tablespace_name,bytes_free,bytes_used) df
 WHERE fs.tablespace_name (+)  = df.tablespace_name
 GROUP BY df.tablespace_name,fs.bytes,df.bytes_free,df.bytes_used
 ORDER BY 4 DESC;

查询结果:

--oracle table size

SELECT * FROM (
SELECT DS.TABLESPACE_NAME, 
SEGMENT_NAME, 
ROUND(SUM(DS.BYTES) / (1024 * 1024)) AS SIZEINMB
  FROM DBA_SEGMENTS DS
  WHERE SEGMENT_NAME IN (SELECT TABLE_NAME FROM DBA_TABLES)
 GROUP BY DS.TABLESPACE_NAME,
       SEGMENT_NAME
ORDER BY SIZEINMB DESC)
WHERE ROWNUM<=100;

查询结果局部截图:

--oracle block(locked object)

SELECT SUBSTR(TO_CHAR(w.session_id),1,5) "WSid",
P1.spid "WPid",
SUBSTR(s1.username,1,12) "WAITING User",
SUBSTR(s1.osuser,1,8) "OS User",
SUBSTR(s1.program,1,20) "WAITING Program",
s1.client_info "WAITING Client",
SUBSTR(TO_CHAR(h.session_id),1,5) "HSid",
P2.spid "HPid",
SUBSTR(s2.username,1,12) "HOLDING User",
SUBSTR(s2.osuser,1,8) "OS User",
SUBSTR(s2.program,1,20) "HOLDING Program",
s2.client_info "HOLDING Client",
o.object_name "HOLDING Object"
FROM v$process P1, v$process P2, v$session S1,
v$session S2, dba_locks w, dba_locks h, dba_objects o
WHERE w.last_convert > 120
AND h.mode_held != 'None'
AND h.mode_held != 'Null'
AND w.mode_requested != 'None'
AND s1.row_wait_obj# = o.object_id
AND w.lock_type(+) = h.lock_type
AND w.lock_id1(+) = h.lock_id1
AND w.lock_id2 (+) = h.lock_id2
AND w.session_id = S1.sid (+)
AND h.session_id = S2.sid (+)
AND S1.paddr = P1.addr (+)
AND S2.paddr = P2.addr (+)
ORDER BY w.last_convert desc;

       --db host cpu

select value busy, inst_id from gv$sysmetric where metric_name='Host CPU Utilization (%)' and group_id=2

查询结果:

  

--db total size

select sum(round(bytes/(1024*1024),2))/1024 sizeinmb from dba_segments where segment_type in ('TABLE', 'TABLE PARTITION', 'TABLE SUBPARTITION') order by bytes desc

查询结果:

  

--other common query

select * from dba_objects;

show parameters;

select * from v$sql;

select * from v$sysstat;

select * from v$segment_statistics;

select * from v$active_session_history;

select * from dba_tab_stats_history;

-- 联机重做日志

select group#, sequence#, members, status from v$log;

alter system switch logfile;

select group#, member, status from v$logfile;

select * from v$log join v$logfile using (group#);

alter database add logfile member '/u04/app/oracle/redo/redo001a.log' to group 1;

alter database add logfile member '/u04/app/oracle/redo/redo002a.log' to group 2;

alter database add logfile member '/u04/app/oracle/redo/redo003a.log' to group 3;

select * from v$logfile;

-- 控制文件

select name from v$controlfile;

select value from v$parameter2 where name = 'control_files';

-- 归档日志

select log_mode from v$database;

select archiver from v$instance;

alter system archive log current;

select name, is_recovery_dest_file from v$archived_log;

-- 快速恢复区

select * from v$recovery_file_dest;

select * from v$recovery_area_usage;

select name, value from v$parameter where name like 'db_recovery%';

alter system set db_recovery_file_dest_size = 10g;

Generate AWR report

[oracle@28d4718eb450 oracle]$ sqlplus / as sysdba

SQL*Plus: Release 12.2.0.1.0 Production on Mon Sep 14 09:52:14 2020

Copyright (c) 1982, 2016, Oracle.  All rights reserved.

Connected to:

Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

SQL> @$ORACLE_HOME/rdbms/admin/awrrpt.sql

Specify the Report Type

~~~~~~~~~~~~~~~~~~~~~~~

AWR reports can be generated in the following formats. Please enter the

name of the format at the prompt.  Default value is 'html'.

'html' HTML format (default)

'text' Text format

'active-html' Includes Performance Hub active report

Enter value for report_type: html

old   1: select 'Type Specified: ',lower(nvl('&&report_type','html')) report_type from dual

new   1: select 'Type Specified: ',lower(nvl('html','html')) report_type from dual

Type Specified:  html

old   1: select '&&report_type' report_type_def from dual

new   1: select 'html' report_type_def from dual

old   1: select '&&view_loc' view_loc_def from dual

new   1: select 'AWR_PDB' view_loc_def from dual

Current Instance

~~~~~~~~~~~~~~~~

DB Id       DB Name       Inst Num     Instance     Container Name

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

 2722566360 ORCLCDB     1 ORCLCDB     CDB$ROOT

Instances in this Workload Repository schema

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  DB Id      Inst Num DB Name      Instance   Host

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

  1465335565 1 ORCL     ORCL   dc6573fc4856

  2722566360 1 ORCLCDB      ORCLCDB   ea25ab458e7a

* 2722566360 1 ORCLCDB      ORCLCDB   28d4718eb450

Using 2722566360 for database Id

Using       1 for instance number

Specify the number of days of snapshots to choose from

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Entering the number of days (n) will result in the most recent

(n) days of snapshots being listed.  Pressing <return> without

specifying a number lists all completed snapshots.

Enter value for num_days: 1

Listing the last day's Completed Snapshots

Instance     DB Name   Snap Id Snap Started Snap Level

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

ORCLCDB      ORCLCDB   1  14 Sep 2020 05:02   1

  2  14 Sep 2020 06:00   1

  3  14 Sep 2020 07:00   1

  4  14 Sep 2020 08:00   1

  5  14 Sep 2020 09:00   1

Specify the Begin and End Snapshot Ids

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Enter value for begin_snap: 2

Begin Snapshot Id specified: 2

Enter value for end_snap: 4

End   Snapshot Id specified: 4

Specify the Report Name

~~~~~~~~~~~~~~~~~~~~~~~

The default report file name is awrrpt_1_2_4.html.  To use this name,

press <return> to continue, otherwise enter an alternative.

Enter value for report_name: 

Using the report name awrrpt_1_2_4.html

<此处省略 html具体内容>

Report written to awrrpt_1_2_4.html

SQL> exit

Disconnected from Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

[oracle@28d4718eb450 oracle]$ ls

audit  awrrpt_1_2_4.html  checkpoints  diag  product

 Chens-MacBook-Pro:~ cxf$ docker ps

CONTAINER ID        IMAGE                                       COMMAND                  CREATED             STATUS                 PORTS                              NAMES

28d4718eb450        store/oracle/database-enterprise:12.2.0.1   "/bin/sh -c '/bin/ba…"   5 hours ago         Up 5 hours (healthy)   0.0.0.0:1521->1521/tcp, 5500/tcp   Oracle-DB

Chens-MacBook-Pro:~ cxf$ docker cp 28d4718eb450:/u01/app/oracle/awrrpt_1_2_4.html /Users/cxf/Documents/

Chens-MacBook-Pro:~ cxf$ cd Documents/

Chens-MacBook-Pro:Documents cxf$ ls

awrrpt_1_2_4.html

 

打开html文件: 

AWR Data:

Base statistics, SQL statistics, Advisor results, Metrics, ASH, etc

ADDM results

 

归档日志

  1. 用sqlplus启用并验证归档日志

Chens-MacBook-Pro:~ cxf$ docker exec -it Oracle-DB /bin/bash

[oracle@28d4718eb450 /]$ sqlplus / as sysdb

SQL*Plus: Release 12.2.0.1.0 Production

Copyright (c) 1982, 2016, Oracle.  All rights reserved.

Use SQL*Plus to execute SQL, PL/SQL and SQL*Plus statements.

Usage 1: sqlplus -H | -V

    -H   Displays the SQL*Plus version and the

  usage help.

    -V   Displays the SQL*Plus version.

Usage 2: sqlplus [ [<option>] [{logon | /nolog}] [<start>] ]

  <option> is: [-AC] [-C <version>] [-L] [-M "<options>"] [-NOLOGINTIME] [-R <level>]

      [-S]

    -AC    Enable Application Continuity.

    -C <version>   Sets the compatibility of affected commands to the

  version specified by <version>.  The version has

  the form "x.y[.z]". For example, -C 10.2.0

    -L   Attempts to log on just once, instead of

  reprompting on error.

    -M "<options>" Sets automatic HTML or CSV markup of output.  The options

  have the form:

  {HTML html_options|CSV csv_options}

  See SQL*Plus User's Guide for detailed HTML and CSV options.

    -NOLOGINTIME   Don't display Last Successful Login Time.

    -R <level>   Sets restricted mode to disable SQL*Plus commands

  that interact with the file system. The level can

  be 1, 2 or 3.  The most restrictive is -R 3 which

  disables all user commands interacting with the

  file system.

    -S   Sets silent mode which suppresses the display of

  the SQL*Plus banner, prompts, and echoing of

  commands.

  <logon> is: {<username>[/<password>][@<connect_identifier>] | / }

      [AS {SYSDBA | SYSOPER | SYSASM | SYSBACKUP | SYSDG | SYSKM | SYSRAC}] [EDITION=value]

    Specifies the database account username, password and connect

    identifier for the database connection.  Without a connect

    identifier, SQL*Plus connects to the default database.

    The AS SYSDBA, AS SYSOPER, AS SYSASM, AS SYSBACKUP, AS SYSDG,

    AS SYSKM and AS SYSRAC options are database administration privileges.

    <connect_identifier> can be in the form of Net Service Name

    or Easy Connect.

      @[<net_service_name> | [//]Host[:Port]/<service_name>]

<net_service_name> is a simple name for a service that resolves

to a connect descriptor.

Example: Connect to database using Net Service Name and the

database net service name is ORCL.

  sqlplus myusername/mypassword@ORCL

Host specifies the host name or IP address of the database

server computer.

Port specifies the listening port on the database server.

<service_name> specifies the service name of the database you

want to access.

Example: Connect to database using Easy Connect and the

Service name is ORCL.

  sqlplus myusername/mypassword@Host/ORCL

    The /NOLOG option starts SQL*Plus without connecting to a

    database.

    The EDITION specifies the value for Session Edition.

  <start> is: @<URL>|<filename>[.<ext>] [<parameter> ...]

    Runs the specified SQL*Plus script from a web server (URL) or the

    local file system (filename.ext) with specified parameters that

    will be assigned to substitution variables in the script.

When SQL*Plus starts, and after CONNECT commands, the site profile

(e.g. $ORACLE_HOME/sqlplus/admin/glogin.sql) and the user profile

(e.g. login.sql in the working directory) are run.  The files may

contain SQL*Plus commands.

Refer to the SQL*Plus User's Guide and Reference for more information.

[oracle@28d4718eb450 /]$ sqlplus / as sysdba

SQL*Plus: Release 12.2.0.1.0 Production on Fri Nov 13 01:16:12 2020

Copyright (c) 1982, 2016, Oracle.  All rights reserved.

Connected to:

Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

SQL> shutdown immediate

Database closed.

Database dismounted.

ORACLE instance shut down.

SQL> startup mount;

ORACLE instance started.

Total System Global Area 1342177280 bytes

Fixed Size     8792536 bytes

Variable Size   402654760 bytes

Database Buffers   922746880 bytes

Redo Buffers     7983104 bytes

Database mounted.

SQL> alter database archivelog;

Database altered.

SQL> alter database open;

Database altered.

SQL> archive log list

Database log mode       Archive Mode

Automatic archival       Enabled

Archive destination       USE_DB_RECOVERY_FILE_DEST

Oldest online log sequence     40

Next log sequence to archive   42

Current log sequence       42

SQL>

 

alter system archive log current;

归档日志已经在快速恢复区中生成:

 

控制文件

两个查询是相同结果

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值