Oracle1

一、為什么要有數據庫

數據庫(Database)是按照數據結構來組織、存儲和管理數據的倉庫,它產生于距今六十多年前,隨著信息技術和市場的發展,特別是二十世紀九十年代以后,數據管理不再僅僅是存儲和管理數據,而轉變成用戶所需要的各種數據管理的方式。

二、有哪些類型的數據庫

層次結構模型:是一種有根結點的定向有序樹
網狀結構模型:按照網狀數據結構建立的數據庫系統稱為網狀數據庫系統
關系結構模型:把一些復雜的數據結構歸結為簡單的二元關系

三、常見的關系型數據庫

Oracle、DB2、Microsoft SQL Server、Microsoft Access、MySQL

四、常見數據庫產品的特征

通過平臺性、安全性、開放性、可伸縮性(并行性)、性能、客戶端支持及應用模式、
操作簡便來分析各個數據庫的優劣勢。
sqlserver
    開放性:只能windows上運行
    安全性:沒有獲得任何安全證書
    性能:多用戶時性能佳
    客戶端支持及應用模式:只支持C/S模式, C/S結構只支持windows客戶用ADO、DAO、OLEDB、ODBC連接
    使用風險:完全重寫的代碼,經歷了長期的測試,不斷延遲,許多功能需要時間來證明。并不十分兼容早期產品。使用需要冒一定風險。
    伸縮性并行性:并行實施和共存模型并不成熟。
    操作性:操作簡單,但只有圖形界面.
Oracle
    開放性:能在所有主流平臺上運行
    安全性:獲得最高認證級別的ISO標準認證
    性能:性能高 保持開放平臺下 TPC-D和TPC-C世界記錄:能在所有主流平臺上運行
    安全性:
    性能:
    客戶端支持及應用模式:
    客戶端支持及應用模式:多層次網絡計算支持多種工業標準,用ODBC、JDBC、OCI等網絡客戶連接.
    使用風險:長時間的開發經驗,完全向下兼容。得到廣泛的應用。完全沒有風險
    伸縮性并行性:很難處理日益增多的用戶數和數據卷
    操作性:較復雜, 同時提供GUI和命令行,在windowsNT和unix下操作相同
MySql
    開放性:能在所有主流平臺上運行
    安全性:
    性能:
    客戶端支持及應用模式:
    使用風險:
    伸縮性并行性:
    操作性:
DB2
    開放性:能在所有主流平臺上運行
    安全性:獲得最高認證級別的ISO標準認證。
    性能:適用于數據倉庫和在線事物處理性能較高
    客戶端支持及應用模式:
    使用風險:在巨型企業得到廣泛的應用,向下兼容性好。風險小。
    伸縮性并行性:DB2具有很好的并行性。DB2把數據庫管理擴充到了并行的、多節點的環境
    操作性:操作簡單,同時提供GUI和命令行,在windowsNT和unix下操作相同
Access
    開放性:
    安全性:
    性能:
    客戶端支持及應用模式:
    使用風險:
    伸縮性并行性:
    操作性:
Sybase
    開放性:
    安全性:
    性能:
    客戶端支持及應用模式:
    使用風險:
    伸縮性并行性:
    操作性:

五、Oracle版本介紹

版本:
    Oracle10g  不支持win7和vista
    Oracle11g  支持市面上所有的操作系統
    Oracle12c

六、Oracle介紹

默認端口是1521

七、Oracle卸載

用Oracle自帶的卸載程序不能從根本上卸載Oracle,從而為下次的安裝留下隱患,那么怎么才能完全卸載Oracle呢?
那就是直接注冊表清除,步驟如下: 
1、 開始->設置->控制面板->管理工具->服務 
    停止所有Oracle服務。 
2、 開始->程序->Oracle - OraHome81->Oracle Installation Products-> 
Universal Installer 
    卸裝所有Oracle產品,但Universal Installer本身不能被刪除 
5、 運行regedit,選擇HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE,按del鍵刪除這個入口。 
6、 運行regedit,選擇HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services,滾動 
這個列表,刪除所有Oracle入口。
7、 運行refedit,
 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application, 
   刪除所有Oracle入口。 
8、 開始->設置->控制面板->系統->高級->環境變量 
    刪除環境變量CLASSPATH和PATH中有關Oracle的設定 
9、 從桌面上、STARTUP(啟動)組、程序菜單中,刪除所有有關Oracle的組和圖標 
10、 刪除\Program Files\Oracle目錄 
11、 重新啟動計算機,重起后才能完全刪除Oracle所在目錄 
12、 刪除與Oracle有關的文件,選擇Oracle所在的缺省目錄C:\Oracle,刪除這個入 
     口目錄及所有子目錄,并從Windows目錄(一般為C:\WINDOWS)下刪除oralce文件等等。 
13、 WIN.INI文件中若有[ORACLE]的標記段,刪除該段 
14、 如有必要,刪除所有Oracle相關的ODBC的DSN 
15、 到事件查看器中,刪除Oracle相關的日志 
說明: 
如果有個別DLL文件無法刪除的情況,則不用理會,重新啟動,開始新的安裝, 
安裝時,選擇一個新的目錄,則,安裝完畢并重新啟動后,老的目錄及文件就可以刪除掉了

八、Oracle11g安裝

Oracle安裝時要解鎖SCOTT和HR這兩個用戶,因為這兩個用戶默認是鎖住的。
解鎖后,要修改一下密碼,一般
scott/triger
hr/hr















九、Oracle組成

1)Oracle數據庫的組成
    分為:一個 Oracle 實例 和一個 Oracle 數據庫組成
        Oracle 數據庫: 位于硬盤上實際存放數據的文件, 這些文件組織在一起, 成為一個邏輯整體, 即為 Oracle 數據庫. 因此在 Oracle 看來, “數據庫” 是指硬盤上文件的邏輯集合, 必須要與內存里實例合作, 才能對外提供數據管理服務。
        Oracle 實例: 位于物理內存里的數據結構. 它由一個共享的內存池和多個后臺進程所組成, 共享的內存池可以被所有進程訪問. 用戶如果要存取數據庫(也就是硬盤上的文件) 里的數據, 必須通過實例才能實現, 不能直接讀取硬盤上的文件。
2)Oracle數據庫結構
    SGA(System Global Area):由所有服務進程和后臺進程共享;
    PGA(Program Global Area):由每個服務進程、后臺進程專有;每個進程都有一個PGA。
3)表空間和數據文件
    表空間為邏輯概念,數據文件為物理概念
    表空間由多個數據文件組成
        數據文件只能屬于一個表空間
4)段、區和塊
    段存在于表空間中
    段是區的集合
    區是數據塊的集合
    數據塊會被映射到磁盤塊
5)數據庫的邏輯和物理結構





十、Oracle數據庫產品服務器端的安裝與數據庫實例配置

1)Oracle服務器的下載
https://www.oracle.com/index.html
2)Oracle服務器的安裝需求
系統需求
    內存需求:
        –   1 GB
    磁盤空間需求:
        swap 區需要1.5BG
        /tmp 目錄需要400 MB 的磁盤空間
        Oracle軟件需要 1.5 GB 到 3.5 GB
        準備1.2 GB 用來重裝數據庫 (可選)
        為快速恢復區準備2.4 GB   (可選)
3)Oracle服務器的安裝步驟詳解
    Oracle安裝步驟win2008
4)Oracle服務介紹
    Oracle * VSS Writer Service - Oracle卷映射拷貝寫入服務
    OracleDBConsole* - Oracle數據庫控制臺服務
    OracleJobScheduler*  - Oracle作業調度服務
    OracleMTSRecoveryService - 服務端控制
    OracleOraDb11g_home1ClrAgent - Oracle數據庫.NET擴展服務的一部分
    OracleOraDb11g_home1TNSListener - 監聽器服務
    OracleService*  - 數據庫服務,是Oracle核心服務該服務

十、SQL*PLUS的使用方法與常見命令

0)登錄
    sqlplus scott/tiger  
    這樣就可以登錄了。
1)顯示設置
set linesize 120;
set pasesize 20;
set feedback off/on;
set serveroutput on/off;
col 列名 for 9999;修改顯示數值列的長度
col 列名 for a10; 修改字符列的長度
2)常用命令
查看系統變量 show all;
查看當前用戶 show user;
查看錯誤 show error;
多行注釋 /**/
單行注釋 --
文件輸出 新寫入(spool 文件地址)繼續寫入(spool 文件地址 append)
關閉(spool off;)    
執行緩沖區命令 /
打開緩沖區文件 ed
清屏 - 2種方式 clear screen;  host cls;
退出 - exit
查詢參數 select * from v$nls_parameters;

十一、Oracle建表空間

1)表空間介紹
    表空間是數據庫中最大的邏輯單位,Oracle數據庫采用表空間將相關的邏輯組件
組合在一起,一個Oracle數據庫至少包含一個表空間。每個表空間由一個或多個
數據文件組成,一個數據文件只能與一個表空間相聯系。
2)表空間類型
    永久性表空間:一般保存表、視圖、過程和索引等的數據
    臨時性表空間:只用于保存系統中短期活動的數據
    撤銷表空間:用來幫助回退未提交的事務數據
3)創建表空間
    Create tablespace 表空間名
    Datafile ‘文件路徑’ size 大小
    Autoextend on/off next 大小 maxsize 大小;
4)查詢表空間
    //查看所有的表空間
    select * from dba_tablespaces;
    //查看所有的表空間的文件
    select * from dba_data_files;
5)修改表空間
    //增加表空間文件
    Alter tablespace 表空間名 add datafile ’文件路徑’ size 大小
    Autoextend on ;
    //修改表空間文件的大小
    Alter database datafile=’文件路徑’ resize 大小;
    //修改表空間的擴展大小和最大值
    Alter database datafile=’文件路徑’ autoextend on next 大小 maxsize 大小;
6)刪除表空間
    drop tablespace 表空間名;
    Drop tablespace 表空間名 including contents and datafiles;

十二、PL/SQL developer工具的常用功能


十三、plsqldev工具的常用功能


十四、數據庫用戶角色與權限

1)三者的介紹
2)三者之間的關系

十五、權限

1)什么是權限
    所有的操作都需要系統的認可,這種認可就是權限。
2)都有哪些權限
     select * from system_privilege_map;
3)限對應
//1.所有用戶所對應的權限
select * from dba_sys_privs;
//2.當前用戶的權限
select * from user_sys_privs;
//3.所有角色對應的權限
    select * from role_tab_privs; 

十六、數據庫用戶

1)系統常見用戶
    sys 超級用戶,主要用來維護系統信息和管理實例,以SYSDBA或SYSOPER角色登錄。
    system  默認的系統管理員,擁有DBA權限,通常用來管理Oracle數據庫的用戶、權限和存儲,以Normal方式登錄。
    scott   示范用戶,使用users表空間。一般該用戶默認密碼為tiger
    
2)查詢系統用戶
    //查詢數據庫里面所有的用戶
    select * from dba_users;
    //查看當前用戶能管理的所有用戶
    select * from all_users;
    //查看當前賬戶
    select * from user_users;

3)解鎖用戶
    alter user hr account lock/unlock;

4)創建用戶
    Create user 用戶名 identified by 密碼 default tablespace 表空間名;

5)修改用戶密碼
    Alter user hr identified by 新密碼;

6)刪除用戶
    Drop user 用戶名 cascade;

十七、角色

正是因為需要把每個權限都要賦給不同的用戶,操作起來沒有那么簡便,所以就有了角色。

1)系統默認角色
Oracle提供了三種標準的角色(role):connect、resource和dba。
    1. connect role(連接角色)
    臨時用戶,特別是那些不需要建表的用戶,通常只賦予他們connect role。     connect是使用Oracle的簡單權限,這種權限只有在對其他用戶的表有訪問時,包括select、insert、update和delete等,才會變得有意義。
    2. resource role(資源角色)
    更可靠和正式的數據庫用戶可以授予RESOURCE role。resource提供給用戶另外的權限以創建他們自己的表、序列、過程、觸發器、索引和簇。
    3. dba role(數據庫管理員角色)
    dba role擁有所有的系統權限--包括無限制的空間限額和給其他用戶授予各種權限的能力。
除此以上角色外;還可以自行創建角色。用戶創建的role可以由表或系統權限或兩者的組合構成。為了創建role,用戶必須具有CREATE ROLE系統權限。

2)創建角色的權限
    grant create role to 用戶名;
3)創建角色
    Create role 角色名;
3)刪除角色
    Drop role 角色名;
4)查詢角色
    //查詢所有角色
    select * from dba_roles;
    //查詢當前用戶所擁有的角色
    select * from user_role_privs;
5)把角色賦給用戶
    Grant 角色名 to 用戶名

十八、DCL數據控制語言

1)授予語法
    Grant 角色 [on 表名] to 用戶;
    Grant 操作 on 表名 to 用戶;
2)授予
    //授予用戶連接權限 -- 用戶在創建的時候有默認表空間。
    Grant connect,resouce to chinasoft;
    //授予用戶的表的操作
    Grant select,update on emp to chinasoft;

    //授予某個角色權限
    Grant connect,resource to 角色名;
    //把角色賦給用戶
    Grant 角色名 to 用戶名;


3)撤銷
    //撤銷權限
    Revoke connect,resource from 用戶;
    Revoke select,update from 用戶;
    //撤銷角色
    Revoke 角色名 from 用戶名;

十九、SQL數據類型

VARCHAR2(size)
    可變長度的字符串,其最大長度為size個字節;size的最大值是4000,而最小值是1;你必須指定一個VARCHAR2的size;

NVARCHAR2(size)
    可變長度的字符串,依據所選的國家字符集,其最大長度為size個字符或字節;size的最大值取決于儲存每個字符所需的字節數,其上限為4000;你必須指定一個NVARCHAR2的size;

NUMBER(p,s)
    精度為p并且數值范圍為s的數值;精度p的范圍從1到38;數值范圍s的范圍是從-84到127;例如:NUMBER(5,2) 表示整數部分最大3位,小數部分為2位;NUMBER(5,-2) 表示數的整數部分最大為7其中對整數的倒數2位為0,前面的取整。NUMBER 表示使用默認值,即等同于NUMBER(5);
    
LONG
    可變長度的字符數據,其長度可達2G個字節;
DATE
    有效日期范圍從公元前4712年1月1日到公元后9999年12月31日

RAW(size)
    長度為size字節的原始二進制數據,size的最大值為2000字節;你必須為RAW指定一個size;
    
LONG RAW
    可變長度的原始二進制數據,其最長可達2G字節;

CHAR(size)
    固定長度的字符數據,其長度為size個字節;size的最大值是2000字節,而最小值和默認值是1;
    
NCHAR(size)
    也是固定長度。根據Unicode標準定義
CLOB
    一個字符大型對象,可容納單字節的字符;不支持寬度不等的字符集;最大為4G字節
NCLOB
    一個字符大型對象,可容納單字節的字符;不支持寬度不等的字符集;最大為4G字節;儲存國家字符集
BLOB
    一個二進制大型對象;最大4G字節

BFILE
    包含一個大型二進制文件的定位器,其儲存在數據庫的外面;使得可以以字符流I/O訪問存在數據庫服務器上的外部LOB;最大大小為4G字節.
    

二十、DDL語言(表操作)

1)什么是表
    用一個excle表來保存一個Student對象。
    注意:用Excel演示出來
2)創建表
    Create table 表名(
    字段 字段類型 約束條件,
    字段 字段類型 約束條件,
    ....
    字段 字段類型 約束條件,
    [約束條件]
    );
3)字段約束
    Primary key
    Unique
    Not null
    Check check(usex in (0,1))/check(uage between 1 and 100)/check(unum > 0)
4)添加約束
    alter table users modify uage constraint users_age not null;
5)刪除約束
    alter table users drop constraint users_unum;
    alter table users modify uage null;
6)查看表
    1.查看當前用戶的所有表
    select * from tabs;
    select * from user_tables;
    2.查看所有用戶的所有表
    select * from dba_tables;
    3.查看當前用戶的所有表(和當前用戶所管理的用戶)
    select * from all_tables;
    4.查看當前用戶所有的表
    select * from tab;
    5.查看表結構
    desc emp;

7)修改表
    1.添加字段
        alter table test01 add(
                sex number(5) not null
            );
    2.修改屬性
        alter table test01 modify(sex number(20),name varchar2(50));
    3.刪除字段
        alter table test01 drop(sex,age); 
    4.修改字段名稱
        alter table test01 rename column name to tname;
    5.修改表名稱
        alter table test01 rename to test00;
        rename test00 to test01;

8)刪除表
    drop table test01;  // 刪除后可以在回收站查看并恢復
    drop table user01 purge;// 刪除后不可以在回收站查看和恢復

二十一、回收站操作

1)回收站是什么

2)查看回收站
    show recycle;
    select * from recyclebin;
3)從回收站恢復表
    flashback table user01 to before drop;
4)清空回收站
    purge recyclebin;

二十二、偽表

1)偽表
    管理員提供的表,查詢的數據跟表沒有關系,但是還需要滿足語法,這個時候就需要用這個偽表。
    select 'zhangsan' from dual;
2)偽列rowid
    select rowid,ename from emp;
3)偽列rownum
    select rownum,ename from emp;

二十三、常用函數

1)數字型
    round 四舍五入
        select round(10.5) from dual;//10.6、10.3   
        select round(10.336,2) from dual; //10.336、10.334
    trunc 精度
    select trunc(20.55) from dual;//20.55、20   
    select trunc(20.55,2) from dual;//0,1,2,3
2)字符串
    lower 轉小寫
        select lower('ZhongRuan') from dual;
    upper 轉大寫
        select upper('zhongruan') from dual;
    initcap 首字母大寫
        select initcap('zhongruan') from dual;
    substr 字符串截取
        select substr('zhongruan',1) from dual;   
        select substr('zhongruan',1,2) from dual;
    length 字符長度
        select length('zhongruan') from dual;  
        select length('中軟') from dual;
    lengthb 字節長度
        select lengthb('中軟') from dual;
    instr 查找子串
        select instr('zhongruan','ruan') from dual;
    lpad 左填充
        select lpad('zhang',10) from dual;  
        select lpad('zhang',10,'*') from dual;
    rpad 右填充
        select rpad('zhong',10) from dual;  
        select rpad('zhong',10,'*') from dual;
    trim 去掉字符
        select trim('z' from 'zhong') from dual;
    replace 替換
        select replace('zhong','o','a') from dual;
    concat 拼接 ||
        select concat('hello',' world') from dual;  
        select 'zhong' || 'ruan' from dual;

3)轉換函數
    to_char 轉成char類型
        select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual; 
        select to_char(sal,'L9,999.99') from emp;
    to_number 轉成number類型
        select to_number('2017') from dual;
    to_date 轉成日期
        select to_date('2017-08-09','yyyy-mm-dd') from dual;
    
4)時間
    date格式 當前時間
        select sysdate from dual;
        select sysdate-1 from dual;
        select sysdate+1 from dual;
    修改日期格式
        alter session set NLS_DATE_FORMAT='yyyy-mm-dd';   
        select sysdate from dual;
        alter session set NLS_DATE_FORMAT='DD-MON-RR';  
        select sysdate from dual;
    timestamp格式 當前時間
        select systimestamp from dual;
    兩種時間格式的區別
        date顯示的是年月日時分秒   
        timestamp顯示的年月日時分秒還包括了小數秒 
    兩種時間格式的轉換
        timestamp轉date:select cast(systimestamp as date) from dual;
        date轉timestamp:select cast(sysdate as timestamp) from dual;
    add_months 增加月
        add_months select add_months(sysdate,1) from dual;
    months_between 時間相距幾月
        select months_between(sysdate,to_date('2017-08-09','yyyy-mm-dd')) from dual;
    extract 獲取年月日時分秒
        select extract(year from sysdate) from dual;  
        select extract(month from sysdate) from dual;  
        select extract(day from sysdate) from dual;   
        select extract(hour from timestamp '2017-03-09 14:05:30') from dual;
    last_day 月末時間
        select last_day(sysdate) from dual;  
    next_day 一周時間 
        select next_day(sysdate,'星期日') from dual;

5)聚合函數
    sum 求和
        select sum(sal) from emp;
    avg 求平均值
        select avg(sal) from emp;
    count 計數
        select count(empno) from emp;
    max 求最大值
        select max(sal) from emp;
    min 求最小值
        select min(sal) from emp;

6)其它函數
    nvl
        提出問題:select ename,sal,comm from emp;  
        解決問題:select ename,sal,nvl(comm,0)comm from emp;
    nvl2(a,b,c)
        當a=null時,返回c; 否則返回b(3元運算符) 
        select ename,sal,nvl2(comm,'有值','沒值')comm from emp;

二十四、DML語言

1)新增數據
    insert into student (id,sname,sage) values(1,'zhangsan',18);
    insert into student values(1,'zhangsan',18);
2)修改數據
    update 表名 set column1=newValue,column2=newValue,...where 條件;
    update users03 set u_age=20,u_sex=2 where u_id=100;
3)刪除數據
    delete from emp where empno = 8888;//根據條件刪除表數據
    truncate table emp01; //清空表數據
4)查詢語句 - 基本查詢
    基本查詢
        select * from emp;
    列名查詢
        select empno from emp;
        select empno,ename from emp;
    查詢時列名加減乘除操作
        select ename,sal+100 from emp;
        select ename,sal-100 from emp;
        select ename,sal*100 from emp;
        select ename,sal/100 from emp;
        select sal*deptno from emp;
    別名
        select ename name,sal*10 sal from emp;
        select empno as "員工號",ename "姓名" ,sal 月薪 from emp;
        
        注意: 有as 和沒有as 與有雙引號和沒有雙引號的區別?
            如果是別名中有空格,就必須要有雙引號。否則就是錯誤的sql。
            
            別名使用雙引號,以便在別名中包含空格或者特殊字符并區分大小寫。
    去重 distinct
        select distinct job from emp;
        distinct作用于多列
        select distinct deptno,job from emp;
            這個是只要deptno,job合起來不相同則不相同。
        

二十五、DML語言-單表復雜查詢

1)過濾查詢 等于
    select * from emp where empno = 7169;
    select * from emp where ename = ‘SMITH’;
    select * from emp where hiredate = '17-12月-1980';

2)過濾查詢 大于小于
    select * from emp where sal > 2000;
    select * from emp where sal < 2000;

3)過濾查詢 在兩個值之間 [a,b]
    select * from emp where sal between 800 and 1600;
    注意:小值在前,大值在后面
4)過濾查詢 在一個集合中 in
    select * from emp where deptno in (20,30);
    
5)過濾查詢 不在一個集合中 not in
    select * from emp where deptno not in(20,30);
    ()括號里面不能出現null

6)過濾查詢 根據兩個條件查詢 and
    select * from emp where sal = 3000 and ename = 'SCOTT';

7)過濾查詢 根據兩個條件查詢 or
    select * from emp where sal = 3000 or sal = 1600;

8)過濾查詢 只要一條數據
    select * from emp where rownum = 1;

9)模糊查詢
    select * from emp where ename like '%S%';
    select * from emp where ename like '%S____';
    select * from emp where ename like '_A__';
    % :模糊匹配,任意多個字符
    _ : 模糊匹配,但是只能匹配一個字符

10)模糊查詢 - 轉義字符
    insert into emp(empno,ename,sal) values(8888,'Zhang_S',3000.00);
    select * from emp where ename like '%\_%' escape '\';
    用a-z都可以。

11)排序 asc(默認)|desc
    select * from emp order by sal;
    select * from emp order by sal desc;

    select * from emp order by deptno,sal;
    select * from emp order by deptno,sal desc;
    //按照兩個列排序

12)排序 order by后面+ 列名 表達式 別名 序號
    select * from emp order by sal;
    select * from emp order by sal*12;
    select empno num,ename name,sal s from emp order by s;
    select empno,ename,sal from emp order by 3;
13)分組 group by 
    //求每個部門的平均工資
    select deptno,avg(sal) from emp group by deptno;
    //按照job和deptno分組
    select job,deptno from emp group by job,deptno;
    //求部門平均工資大于2000的部門
    select deptno from emp group by deptno having avg(sal) > 2000;
    //求10號部門的平均工資
    select deptno,avg(sal) from emp group by deptno having deptno = 10;


注意:
    在分組查詢中只能出現分組列和聚合函數。
    在分組查詢中,條件列必須出現在group by后。
    在分組查詢中,group by后可以有多列,但是必須要出現在查詢條件中。

二十六、DML語言-多表復雜查詢

1)笛卡爾集
    沒有WHERE子句的交叉聯接將產生聯接所涉及的表的笛卡爾集。
    select * from emp,dept;
2)查詢員工信息:員工號 姓名 月薪 部門名稱
    select e.empno,e.ename,e.sal,d.dname from emp e,dept d where e.deptno = d.deptno;
3)按部門統計員工人數: 部門號  部門名稱 人數
    select d.deptno,d.dname,count(e.empno) from emp e,dept d where e.deptno = d.deptno group by d.deptno,d.dname;
先查
    select d.deptno,d.dname from emp e,dept d where e.deptno = d.deptno;
再統計
4)外連接
    外連接:對于不成立的記錄,任然希望包含在最后的結果中
    左外連接: where e.deptno=d.deptno 不成立時,等號左邊所代表的表任然被包含
    where e.deptno=d.deptno(+)
    等號左邊的是左表,等號右邊的是右表
    右外連接: where e.deptno=d.deptno 不成立時,等號右邊所代表的表任然被包含
    where e.deptno(+)=d.deptno
    等號左邊的是左表,等號右邊的是右表
5)左外:按部門統計員工人數: 部門號  部門名稱 人數(包含部門沒有人的部門)
    Dept表中有多余的部門,emp表中的員工都是有部門的。所以dept表是左表
    select d.deptno,d.dname,count(e.empno) from emp e,dept d where  d.deptno = e.deptno(+) group by d.deptno,d.dname;

    Left join寫法--leftjoin 左邊的是左表  右邊的是右表
    select d.deptno,d.dname,count(e.empno) from dept d left join emp e on d.deptno = e.deptno group by d.deptno,d.dname;


6)右外:按部門統計員工人數: 部門號  部門名稱 人數(包含部門沒有人的部門)
    select d.deptno,d.dname,count(e.empno) from emp e,dept d where e.deptno(+) = d.deptno group by d.deptno,d.dname;

Right join寫法--rightjoin 左邊是右表  右邊是左表
    select d.deptno,d.dname,count(e.empno) from emp e right join dept d on e.deptno = d.deptno group by d.deptno,d.dname;

7)內連接 inner join
    只返回兩個表中聯結字段相等的行
    查詢員工信息:員工號 姓名 月薪 部門名稱
    select e.empno,e.ename,e.sal,d.dname from emp e,dept d where d.deptno = e.deptno;

    select e.empno,e.ename,e.sal,d.dname from emp e inner join dept d on d.deptno = e.deptno;

8)自連接
    查詢的多個表都是自己一張表
    查詢員工信息: ***的老板是***
    select e.ename||'的老板是'||b.ename from emp e,emp b  where e.mgr=b.empno;

二十七、DML語言-子查詢

1)步驟
    條件是一條查詢語句,返回值是主查詢的范圍。
    先把子查詢語句寫出來,然后再寫主查詢

2)查詢工資比SCOTT高的員工信息
    select sal from emp where ename = 'SCOTT';
    select * from emp where sal > 3000;
    select * from emp where sal > (select sal from emp where ename = 'SCOTT');

3)查詢員工的姓名 和薪水
    select ename,sal from emp;
    select * from (select ename,sal from emp);

4)查詢部門名稱為SALES的員工信息
    select deptno from dept where dname = 'SALES';
    select * from emp where deptno = (select deptno from dept where dname = 'SALES');

5)查詢部門名稱為SALES和ACCOUNTING的員工信息
    select deptno from dept where dname='SALES' or dname='ACCOUNTING';
    select * from emp where deptno in (select deptno from dept where dname='SALES' or dname='ACCOUNTING');

    select e.* from emp e,dept d where e.deptno=d.deptno and (d.dname='SALES' or d.dname='ACCOUNTING');

6)查詢工資比30號部門任意一個員工高的員工信息
    select sal from emp where deptno=30;
    select * from emp where sal > any (select sal from emp where deptno=30);

7)查詢工資比30號部門所有員工都高的員工信息
    select * from emp where sal >all (select sal from emp where deptno=30);

8)集合合并 union 和 union all 
    union : 多個結果合并在一起顯示出來,沒有重復
    union all : 將所有的結果全部顯示出來,不管是不是重復

    select * from emp where deptno = 10
    union
    select * from emp where ename = 'CLARK'


    select * from emp where deptno = 10
    union all
    select * from emp where ename = 'CLARK'

9)交集 intersect
    對兩個結果集進行交集操作,不包括重復行

    select * from emp where deptno = 10
    intersect
    select * from emp where deptno = 20

    select * from emp where deptno = 10
    intersect
    select * from emp where ename = 'CLARK'

10)minus
    對兩個結果集進行差操作,不包括重復行
    minus 前邊是大集合,后邊是小集合。寫反的結果不同

    //有結果
    select * from emp where deptno = 10
    minus
    select * from emp where ename = 'CLARK'

    //沒有結果
    select * from emp where ename = 'CLARK'
    minus
    select * from emp where deptno = 10

11)exists 和 not exists

    exists表示()內子查詢語句返回結果不為空說明where條件成立就會執行主sql語句,如果為空就表示where條件不成立,sql語句就不會執行。

    帶有EXISTS謂詞的子查詢不返回任何數據,只產生邏輯真值“true”或邏輯假值“false”。 
    使用存在量詞EXISTS后,若內層查詢結果非空,則外層的WHERE子句返回真值否則返回假值。 
    由EXISTS引出的子查詢,其目標列表達式通常都用*,因為帶EXISTS的子查詢只返回真值或假值,給出列名無實際意義。 

如果部門名稱以字母A開頭,則查詢所有員工信息(使用exists)
    select * from dept where dname like 'A%';
    select * from emp where deptno = 10;
    select * from emp where exists (select * from dept where dname like 'A%' and emp.deptno = deptno)
    先看部門名稱是否是A開頭,然后 emp表的deptno 和 dept表的deptno必須相同者兩個條件去查詢emp表

    not exists和exists相反,子查詢語句結果為空,則表示where條件成立,執行sql語句。負責不執行

    查詢10號部門以外的員工
        select a.deptno,a.ename from scott.emp a where not exists(select * from scott.dept b where b.deptno=a.deptno and b.deptno=10) ;

二十八、TCL事務控制語言

1)什么是事務
    事務是應用程序中一系列嚴密的操作,所有操作必須成功完成,否則在每個操作中所作的所有更改都會被撤消。
    一個事務中的一系列的操作要么全部成功,要么一個都不做。 
    事務的結束有兩種,當事務中的所以步驟全部成功執行時,事務提交。如果其中一個步驟失敗,將發生回滾操作,撤消撤消之前到事務開始時的所以操作。
2)事務的特性
    原子性(Atomicity)
        事務是數據庫的邏輯工作單位,事務中包含的各操作要么都做,要么都不做

    一致性(Consistency)
        事務執行的結果必須是使數據庫從一個一致性狀態變到另一個一致性狀態。 

    隔離性(Isolation)
        一個事務的執行不能其它事務干擾。即一個事務內部的操作及使用的數據對其它并發事務是隔離的,并發執行的各個事務之間不能互相干擾。

    持久性(Durability)
        也稱永久性,指一個事務一旦提交,它對數據庫中的數據的改變就應該是永久性的。接下來的其它操作或故障不應該對其執行結果有任何影響。 


案例:
    小明去銀行給小紅轉錢。小明卡上有1000,小紅卡上有500,小明給小紅轉500塊
    步驟:1.從小明卡里扣除500  2.在小紅的卡里加500    
        最后的結果小明卡里有500,小紅卡里有1000.如果從小明的卡里扣了500,然后程序報錯了,結果應該怎樣?

3)臟讀
    臟讀又稱無效數據的讀出,是指在數據庫訪問中,事務T1將某一值修改,然后事務T2讀取該值,此后T1因為某種原因撤銷對該值的修改,這就導致了T2所讀取到的數據是無效的。

臟讀:一個事務讀取到了另外一個事務沒有提交的數據
    事務1:更新一條數據
        -->事務2:讀取事務1更新的記錄
    事務1:調用commit進行提交
    
    此時事務2讀取到的數據是保存在數據庫內存中的數據,稱為臟讀。
    讀到的數據為臟數據
    詳細解釋:
        臟讀就是指:當一個事務正在訪問數據,并且對數據進行了修改,而這種修改還沒有提交到數據庫中,這時,另外一個事務也訪問這個數據,然后使用了這個數據。因為這個數據是還沒有提交的數據,那么另外一個事務讀到的這個數據是臟數據,依據臟數據所做的操作可能是不正確的。

4)不可重復讀
    在同一事務中,兩次讀取同一數據,得到內容不同
    事務1:查詢一條記錄
        --->事務2:更新事務1查詢的記錄
       --->事務2:調用commit進行提交
    事務1:再次查詢上次的記錄
        此時事務1對同一數據查詢了兩次,可得到的內容不同,稱為不可重復讀

5)幻讀
    同一事務中,用同樣的操作讀取兩次,得到的記錄數不相同
    事務1:查詢表中所有記錄
         -->事務2:插入一條記錄
         -->事務2:調用commit進行提交
    事務1:再次查詢表中所有記錄

    此時事務1兩次查詢到的記錄是不一樣的,稱為幻讀
    詳細解釋:
        幻讀是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的全部數據行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那么,以后就會發生操作第一個事務的用戶發現表中還有沒有修改的數據行,就好象發生了幻覺一樣。

6)事務的隔離級別
    TRANSACTION_NONE  不使用事務。
    TRANSACTION_READ_UNCOMMITTED  允許臟讀。
    TRANSACTION_READ_COMMITTED  防止臟讀,最常用的隔離級別,并且是大多數數據庫的默認隔離級別
    TRANSACTION_REPEATABLE_READ  可以防止臟讀和不可重復讀,
    TRANSACTION_SERIALIZABLE  可以防止臟讀,不可重復讀取和幻讀,(事務串行化)會降低數據庫的效率

7)事務操作-保存點
    savepoint 保存點名稱
8)事務操作-提交
    commit;
9)事務操作-回滾
    rollback to 保存點;

二十九、TCL事務控制語言

1)運算符介紹

2)算術運算符
    +、-、*、/
    
    乘除的優先級高于加減。
    優先級相同時,按照從左至右運算
    可以使用括號改變優先級。

3)比較(關系)運算符
    =、!=、<>、< 、 > 、 <= 、 >= 、 between...and... 、in 、like 、is null

4)邏輯運算符
    AND(邏輯與),表示兩個條件必須同時滿足
    OR(邏輯或),表示兩個條件中有一個條件滿足即可
    NOT(邏輯非),返回與某條件相反的結果

5)連接運算符
    ||
    把列與列,列與字符連接在一起。可以用來'合成'列。
    select ename || '的職位是' || job from emp;

6)集合運算符
    union(并集無重復)
    union all(并集有重復)
    intersect(交集,共有部分)
    minus(減集,第一個查詢具有,第二個查詢不具有的數據)
7)運算符優先級
    1   算術運算符
    2   連接符
    3   比較符
    4   IS[NOT]NULL, LIKE, [NOT]IN
    5   [NOT] BETWEEN
    6   NOT
    7   AND
    8   OR
    可以使用括號改變優先級順序;OR的優先級最低,算術運算符的優先級最高。

三十、視圖

1)什么是視圖
    視圖是由一個或者多個表組成的虛擬表;那些用于產生視圖的表叫做該視圖的基表。視圖不占用物理空間,這個也是相對概念,因為視圖本身的定義語句還是要存儲在數據字典里的。視圖只有邏輯定義。每次使用的時候只是重新執行SQL。一個視圖也可以從另一個視圖中產生。視圖沒有存儲真正的數據,真正的數據還是存儲在基表中。一般出于對基本的安全性和常用的查詢語句會建立視圖;并一般情況下不對視圖進行新增、更新操作。

2)視圖的作用
    1、視圖能夠簡化用戶的操作
    2、視圖使用戶能以多鐘角度看待同一數據
    3、視圖對重構數據庫提供了一定程度的邏輯獨立性
    4、視圖能夠對機密數據提供安全保護
    5、適當的利用視圖可以更清晰的表達查詢
3)視圖的語法
    create or replace view 視圖名稱
    as
    Select 語句;
4)創建視圖的權限
    grant create view to 用戶;
5)視圖操作
    查詢數據
        select * from 視圖名;
    添加數據
        insert into 視圖名(字段,字段) values(值,值);
    修改數據
        update 視圖名 set 字段=值 where 條件;
    刪除數據
        delete from 視圖名 where 條件;
    基于多個表建立視圖
        create or replace view v_emp_dept 
        as
        select e.empno,e.ename,e.job,e.mgr,e.hiredate,e.sal,e.comm,d.deptno,d.dname,d.loc from emp e,dept d where e.deptno = d.deptno;

6)刪除視圖
    drop view 視圖名;

三十一、同義詞

1)同義詞介紹
    同義詞是數據庫模式對象的一個別名,經常用于簡化對象訪問和提高對象訪問的安全性。在使用同義詞時,Oracle數據庫將它翻譯成對應模式對象的名字。與視圖類似,同義詞并不占用實際存儲空間,只有在數據字典中保存了同義詞的定義。在Oracle數據庫中的大部分數據庫對象,如表、視圖、同義詞、序列、存儲過程等,數據庫管理員都可以根據實際情況為他們定義同義詞。隱藏對象名稱和所有者。

2)同義詞分類
    私有同義詞
        私有同義詞由創建它的用戶所有
    共有同義詞
        公有同義詞由一個特殊的用戶組Public所擁有。顧名思義,數據庫中所有的用戶都可以使用公有同義詞。公有同義詞往往用來標示一些比較普通的數據庫對象,這些對象常需要引用。公有同義詞一般由管理員用戶創建及刪除。

3)創建私有同義詞權限
    grant create synonym to 用戶;

4)創建私有同義詞
    create synonym 同義詞名 for 表;
    create synonym 同義詞名 for 視圖;

5)私有同義詞操作
    select 字段,字段.. from 同義詞名;
    update 同義詞名 set 字段=值 where 條件;

6)刪除私有同義詞
    drop synonym 同義詞名;

7)創建共有同義詞權限
    grant create public synonym to 用戶名;
    grant drop public synonym to 用戶名;

8)創建共有同義詞
    create public synonym 同義詞名 for 表;

9)共有同義詞操作
    查詢數據
    select * from 同義詞名;

10)刪除共有同義詞
    drop public synonym 同義詞名;

三十二、索引

1)索引介紹
    索引是建立在數據庫表中的某些列的上面,是與表關聯的,可提供快速訪問數據方式,但會影響增刪改的效率.

2)索引分類
    單列索引和組合索引
    唯一索引和非唯一索引

3)什么時候需要創建索引
    1.在經常需要搜索、主鍵、連接的列上
    2.表很大,記錄內容分布范圍很廣
    3.在經常需要根據范圍進行搜索的列上創建索引,因為索引已經排序,其指定的范圍是連續的
    4.在經常使用在WHERE子句中的列上面創建索引

4)什么時候不要創建索引
    1.表經常進行 INSERT/UPDATE/DELETE 操作
    2.表很小(記錄超少)
    3.列名不經常作為連接條件或出現在 WHERE 子句中
    4.對于那些定義為text, image和bit數據類型的列不應該增加索引

5)創建索引的準則
    1.如果表里有幾百行記錄則可以對其創建索引(表里的記錄行數越多索引的效果就越明顯)。
    2.不要試圖對表創建兩個或三個以上的索引。
    3.為頻繁使用的行創建索引。

6)新建索引
    單列索引
        create index 索引名 on 表名(字段名);
    單列唯一索引
        create unique 索引名 on 表名(字段名);
    組合索引
        create index 索引名 on 表名(字段,字段..);
    組合唯一索引
        create unique 索引名 on 表名(字段,字段..);

7)刪除索引
    drop index 索引名;

三十三、序列

1)什么是序列
    序列是oracle提供的一個產生唯一數值型值的機制。通常用于表的主健值,序列只能保證唯一,不能保證連續。

2)序列語法介紹
    Create sequence 序列名
    [increment by n]
    [start with n]
    [maxvalue n][minvalue n]
    [cycle|nocycle]
    [cache|nocache];

    increment by n --表示序列每次增長的幅度;默認值為1.
    start with n --表示序列開始時的序列號。默認值為1.
    maxvalue n --表示序列可以生成的最大值(升序).
    minvalue n --表示序列可以生成的最小值(降序).
    cycle --表示序列到達最大值后,在重新開始生成序列.默認值為 nocycle。
    cache n--允許更快的生成序列.預先生成n個序列值到內存(如果沒有使用完,那下次序列的值從內存最大值之后開始;所以n不應該設置太大)

    cycle|nocycle 是否到極限值循環    cache|nocache 存放序列的內存塊的大小,默認為20

3)新建序列

    --遞增
    create sequence seq_upper
    increment by 1
    start with 1
    maxvalue 10000
    nocycle;

    --遞減
    create sequence seq_lower
    increment by -1
    start with 10000
    maxvalue 10000
    minvalue 1
    nocycle;

4)查詢當前值
    currval返回序列的當前值.注意在剛建立序列后,序列的currval值為NULL,所以不能直接使用。使用過nextval訪問序列后才能使用
    select 序列名.currval from dual;

5)查詢下一個值
    nextval 返回序列下一個值;第一次訪問時,返回序列的初始值,后繼每次調用時,按步長增加的值返回
    select 序列名.nexval from dual;

6)往表中插入一條數據
    insert into 表名(id,字段名) values(序列名.nextval,值);

7)修改序列
    alter sequence 序列名
    maxvalue 9999
    cycle;

8)刪除序列
    drop sequence 序列名;

9)sys_guid()方法的使用
    select sys_guid() from dual;

三十四、分區表

1)分區表介紹
    分區表通過對分區列的判斷,把分區列不同的記錄,放到不同的分區中。分區完全對應用透明。Oracle的分區表可以包括多個分區,每個分區都是一個獨立的段(SEGMENT),可以存放到不同的表空間中。查詢時可以通過查詢表來訪問各個分區中的數據,也可以通過在查詢時直接指定分區的方法來進行查詢。

2)分區表的優缺點
    1.由于將數據分散到各個分區中,減少了數據損壞的可能性;
    2.可以對單獨的分區進行備份和恢復;
    3.可以將分區映射到不同的物理磁盤上,來分散IO;
    4.提高可管理性、可用性和性能。
    數據量大的表,一般大于2GB;數據有明顯的界限劃分;對于Long和Long Raw類型列不能使用分區。

3)分區表的分類
    范圍分區,散列分區,列表分區
    復合分區(范圍-散列分區,范圍-列表分區)
    間隔分區和系統分區

4)范圍分區語法介紹
    范圍分區根據數據庫表中某一字段的值的范圍來劃分分區。

    create table 表名(
        字段,
        字段
        ..
        約束
    )
    partition by range(字段)(
        partition 范圍名 values less than (范圍值) [tablespace 表空間名],
        partition 范圍名 values less than (范圍值) [tablespace 表空間名],
        ..
        partition 范圍名 values less than (maxvalue) [tablespace 表空間名]
    );

    maxvalue:當分區列值都不在設置的范圍內時,新增數據將到這個分區中

5)創建范圍分區表
    create table myemp(
           empno number(4) primary key,
           ename varchar2(20),
           hiredate date,
           sal number(7,2),
           deptno number(2)
    )
    partition by range(sal)(
              partition part1 values less than(1000),
              partition part2 values less than(2000),
              partition part3 values less than(3000),
              partition part4 values less than(maxvalue)
    );

//插入數據
    insert into myemp(empno,ename,hiredate,sal,deptno) select empno,ename,hiredate,sal,deptno from emp;

6)范圍分區表操作
    查詢全部
    select * from myemp;

    查詢分區
    select * from myemp partition(part1);

    刪除數據
    delete from myemp partition(part1);

7)列表分區表語法介紹
    列表分區明確指定了根據某字段的某個具體值進行分區,而不是像范圍分區那樣根據字段的值范圍來劃分的。

    create table 表名(
      字段,
      字段
      ..
      約束
    )
    partition by list(字段)(
              partition part1 values (值),
              ..
              partition partn values (default)
    );

    column_name是以其為基礎創建列表分區的列。
    part1...partN是分區的名稱。
    值 是對應分區的分區鍵值的列表。
    default關鍵字允許存儲前面的分區不能存儲的記錄。

8)創建列表分區表

    create table myemp(
           empno number(2),
           ename varchar2(20),
           sal number(7,2),
           deptno number(2)
    )
    partition by list(deptno)(
              partition part1 values(10),
              partition part2 values(20),
              partition part3 values(30),
              partition part4 values(40),
              partition part5 values(default)
    );

    //插入數據
    insert into myemp(empno,ename,sal,deptno) select empno,ename,sal,deptno from emp;


9)列表分區表操作
    查詢全部
    select * from myemp;

    查詢分區
    select * from myemp partition(part1);

    刪除數據
    delete from myemp partition(part1);

三十五、PL/SQL

1)PL/SQL介紹
    pl/sql:塊結構語言,是sql(Structured Query Language)語言的一種擴展,結合了oracle過程語言(procedural language)進行使用。

2)PL/SQL構成
    pl/sql塊由三部分構成:聲明部分、執行部分、異常部分。

3)PL/SQL語法介紹
    declare
      --變量聲明區;
    begin
      --程序主要部分,一般用來執行sql語句或者過程語句
      [exception]
        --異常處理;
    end;

4)PL/SQL中的運算符
    比較運算符
        =   等于   
        <>,!=,~=,^= 不等于 
        <   小于  
        >   大于  
        <=  小于或等于   
        >=  大于或等于   
    算術運算符
         +  加號   
         -  減號  
         *  乘號  
         /  除號  
    賦值運算符
        :=  賦值號 
    關系號
        =>  關系號 
    范圍運算符
        ..  范圍運算符
    連接運算符
        ||  字符連接符
    邏輯運算符
        is null 是空值  
        between and 介于兩者之間  
        in  在一系列值中間 
        and 邏輯與 
        or  邏輯或 
        not 取反  

5)變量
    變量名 類型 [:= 初始值];
    name varchar2(20);
    age number(2) := 20;

6)常量
    變量名 constant 類型 := 初始值;
    papa constant varchar2(20) := ‘啪啪’;

7)屬性類型
    %type
    可以用來定義數據變量的類型與已定義的數據變量(表中的列)一致。
    變量名 表名.列名%type;
    name emp.ename%type;

    %rowtype
    與某一數據庫表的結構一致(修改數據庫表結構,可以實時保持一致);訪問方式聲明為rowtype的 變量名.字段名。
    變量名 表名%rowtype;
    emp_rowinfo emp%rowtype;

8)輸出hello world
    declare
      hi varchar(20) := 'hello world'; 
    begin
      dbms_output.put_line(hi);
    end;


9)條件語句 if..elsif..else..end if

    declare
      testempno number(4) := 7499; -- 7369 7499 7566
      test_sal emp.sal%type;
    begin
      select sal into test_sal from emp where empno = testempno;

      if test_sal < 1000 then
         dbms_output.put_line('努力工作');
      elsif test_sal < 2000 then
            dbms_output.put_line('繼續努力工作');
      else 
         dbms_output.put_line('加油!');
      end if;
    end;

    注意:指定順序執行的語句;主要包括 null語句。null語句:是一個可執行語句,相當于一個占位符或不執行操作的空語句。主要用來提高程序語句的完整性和程序的可讀性。

    declare
       test_num number(2) := 10;
    begin
      loop
       test_num := test_num - 1;
       if test_num = 4 then
          null;
       else 
          dbms_output.put_line(test_num);
       end if;
       exit when test_num = 0;
      end loop;
    end;


10)循環語句 loop 

    loop

    exit when 條件;
    end loop;

    declare
      test_num number(3) := 100;
      test_sum number(4) := 0;
    begin
      loop
        test_sum := test_sum + test_num;
        test_num := test_num - 1;
        exit when test_num = 0;
      end loop;
      dbms_output.put_line(test_sum);
    end;


11)循環語句 while loop
    while 條件
    loop
    語句;
    end loop;

    declare
      test_num number(3) := 100;
      test_sum number(4) := 0;
    begin
      while test_num > 0
      loop 
            test_sum := test_sum + test_num;
            test_num := test_num - 1;
      end loop;
      dbms_output.put_line(test_sum);
    end;


12)循環語句for
    for 變量 in [reverse] start .. end
    loop
     語句;
    end loop;

..兩點表示范圍。
    1..100表示時將從1到100進行循環,起始(例如 1)寫前邊。
    reverse表示反轉,循環時變成從100到1進行。

    declare
      test_sum number(4) := 0;
    begin
      for test_num in 1..100
      loop
          test_sum := test_sum + test_num;
      end loop;
      dbms_output.put_line(test_sum);
    end;

13)異常介紹
    程序會遇到錯誤或未預料到的事件。一個優秀的程序都應該能夠正確處理各種出錯情況,并盡可能從錯誤中恢復。


    cursor_already_open 試圖"OPEN"一個已經打開的游標  
    dup_val_on_index 試圖向有"UNIQUE"中插入重復的值 
    invalid_cursor 試圖對以關閉的游標進行操作  
    invalid_number 在SQL語句中將字符轉換成數字失敗  
    login_denied 使用無效用戶登陸  
    no_data_found 沒有找到數據時  
    not_login_on 沒有登陸Oracle就發出命令時  
    program_error PL/SQL存在諸如某個函數沒有"RETURN"語句等內部問題  
    storage_error PL/SQL耗盡內存或內存嚴重不足  
    timeout_on_resource Oracle等待資源期間發生超時  
    too_many_rows "SELECT INTO"返回多行時  
    value_error 當出現賦值錯誤  
    zero_divide 除數為零  

14)異常語法
    Exception
    When 異常類型 then
    語句;
    When others then
    語句;
    15)Sqlcode與sqlerrm介紹
    sqlcode 函數 :返回錯誤代碼
    sqlerrm 函數 :返回錯誤信息

    declare
      test_result number(20);
    begin
      test_result := 1/0;
      dbms_output.put_line('no error');
      exception
          when zero_divide then
               dbms_output.put_line('can not divide zero');
          when others then
               dbms_output.put_line('no error');
    end;

16)自定義異常
    自定義異常:程序在運行過程中,根據業務等情況,認為非正常情況,可以自定義異常。
    對于這種異常,主要分三步來處理: 
    1、定義相關異常;在聲明部分定義相關異常,
        格式:<自定義異常名稱>exception;
    2、拋出異常;在出現異常部分拋出異常,
        格式:raise <異常名稱>;
    3、處理異常;在異常處理部分對異常進行處理,
        格式:when <自定義異常名稱> then ...,
    處理異常也可以使用
    raise_application_error(error_number,error_message)存儲過程進行處理,其中參數error_number取值為-20999~-20000的負整數,參數error_message為異常文本消息。

    declare
      test_comm emp.comm%type;
      comm_exception exception;
    begin
      select nvl(comm,0) into test_comm from emp where empno = 7499;
      if test_comm > 1000 then
         dbms_output.put_line('this is over 1000');
      else 
         raise comm_exception;
      end if;

      exception
         when comm_exception then
              dbms_output.put_line('comm can not lower 1000');
         when others then
              dbms_output.put_line('comm is normal');
    end;

三十六、游標

1)什么是游標
    游標是映射在結果集中一行數據上的位置實體,使用游標,便可以訪問結果集中的任意一行數據了,將游標放置到某行后,即可對該行數據進行操作;從上向下依次迭代結果集。
2)游標的語法
    cursor 游標名 is 查詢語句;
3)游標操作
    打開游標
    open 游標名;
    關閉游標
    close 游標名;
    賦值
    fetch 游標名 into 變量1,變量2,...變量n;
    fetch 游標名 into 行對象;


4)游標屬性
    %notfound --如果FETCH語句失敗,則該屬性為"true",否則為"false";  
    %found --如果FETCH語句成果,則該屬性為"true",否則為"false"; 
    %rowcount --返回游標當前行的行數;  
    %isopen --如果游標是開的則返回"true",否則為"false";  


5)游標使用
    1、使用游標顯示員工表中所有的員工姓名、工作和工資

    declare
      emp_info emp%rowtype;
      cursor select_emp_info is select * from emp;
    begin
      open select_emp_info;
      loop
         fetch select_emp_info into emp_info;
         dbms_output.put_line('員工姓名' || emp_info.ename);
                    exit when select_emp_info%notfound;
                 end loop;
    end;

2、使用游標顯示指定部門下的所有的員工姓名、工作和工資

    declare
      emp_info emp%rowtype;
      cursor cur_emp_info(dno emp.deptno%type) is select * from emp where deptno = dno;
    begin
      open cur_emp_info(20);
      loop
           fetch cur_emp_info into emp_info;
           dbms_output.put_line('員工姓名:'||emp_info.ename);
           exit when cur_emp_info%notfound;
      end loop;
    end;

3、使用游標按員工的工種漲工資,總裁800,經理600,其他人員300
    declare
      cursor cur_emp_info is select * from emp;
      emp_info emp%rowtype;
    begin
      open cur_emp_info;
      loop    
              fetch cur_emp_info into emp_info;
              exit when  cur_emp_info%notfound;
              if 'PRESIDENT' = emp_info.job then
                 update emp set sal = sal+800 where empno = emp_info.empno;
              elsif 'MANAGER' = emp_info.job then
                 update emp set sal = sal+500 where empno = emp_info.empno;
              else
                 update emp set sal = sal+300 where empno = emp_info.empno;
              end if;
      end loop;
      close cur_emp_info;
      commit;
    end;

6)隱式游標

    當執行一個SQL語句時,Oracle會自動創建一個隱式游標,隱式游標主要處理DML語句,該游標的名稱是sql。隱試游標不能進行"open" ,"close","fetch"這些操作。

    begin
          update emp set comm = comm + 300 where empno = 7369;
          if sql%notfound then
             dbms_output.put_line('員工不存在');
          else 
             dbms_output.put_line('對應的員工數:' || sql%rowcount);
          end if;
    end;

三十七、存儲過程

1)什么是存儲過程
    存儲過程是命名的pl/sql程序塊,封裝數據業務操作,具有模塊化、可重用、可維護、更安全特點;并且可以被程序調用。

2)什么時候用存儲過程[]

3)存儲過程分類
    一般有4類型的存儲過程,分別為不帶參數、帶輸入參數、帶輸出參數、帶輸入輸出參數。

4)存儲過程語法

    create or replace procedure 過程名[參數列表] as|is
    [局部變量聲明]
    begin
           可執行語句;
           exception 異常語句;
    end;

    or replace:如果系統已存在該存儲過程,將被替換 
    參數列表:參數不需要聲明長度,可選
    參數變量的類型:in 為默認類型,表示輸入; out 表示只輸出;in out 表示即輸入又輸出;

    is 和 as 沒有區別

5)不帶參數的

    create or replace procedure pro_onetest as
    begin
        dbms_output.put_line('this is the first procedure');   
    end;


  create or replace procedure test04
  as
  t_name emp.ename%type;
  t_sal emp.sal%type;
  begin
        select ename,sal into t_name,t_sal from emp where empno = 7369;
        dbms_output.put_line(t_name);
        dbms_output.put_line(t_sal);
  end;


// 調用存儲過程
    begin
        pro_onetest();
    end;

6)帶輸入參數

    create or replace procedure pro_emp_output(p_empno in emp.empno%type) as
    test_name emp.ename%type;
    begin
        select ename into test_name from emp where empno = p_empno;
        dbms_output.put_line(test_name);
    end;

    begin
        pro_emp_output(7369);
    end;


7)帶輸出參數

     create or replace procedure test05(
            t_comm out emp.comm%type
     )as
     begin
           select comm into t_comm from emp where empno = 7499;
     end;

    //調用方式
     declare
       test_com emp.comm%type;
     begin
     test05(test_com);
     dbms_output.put_line('test_com='||test_com);
     end;

8)帶輸入輸出參數

     create or replace procedure test05(
            t_empno emp.empno%type,
            t_comm out emp.comm%type
     )as
     t_name emp.ename%type;
     t_sal emp.sal%type;
     begin
           select ename,sal,comm into t_name,t_sal,t_comm from emp where empno = t_empno;
           dbms_output.put_line(t_name);
           dbms_output.put_line(t_sal);
     end;

    //調用方式
     declare
       test_com emp.comm%type;
     begin
     test05(7369,test_com);
     dbms_output.put_line('test_com='||test_com);
     end;

9)查詢所有的存儲過程
    select * from user_procedures;

10)刪除存儲過程
    drop procedure 過程名;

11)查詢存儲過程的具體內容
    select * from all_source where type = 'PROCEDURE' AND owner = 'SCOTT';

三十八、存儲函數

1)什么是存儲函數
    存儲函數與過程不同的是,存儲函數有return語句;一般情況下如果在需要一個返回值時可使用存儲函數。

2)存儲函數語法介紹
    create or replace function 函數名[參數列表] return 數據類型
    is|as
    [局部變量聲明]
    begin
           可執行語句;
           exception 異常;
           return 值;
    end;

    變量的類型:in 為默認類型,表示輸入; out 表示只輸出;in out 表示即輸入又輸出;

    is 和 as 沒有區別

3)無參存儲函數
    create or replace function fun_one return varchar2 is
    begin
           return 'hello world';
    end;

    declare
           str varchar2(20);
    begin
           str := fun_one();
           dbms_output.put_line(str);
    end;

4)有輸入參數的存儲函數

    create or replace function fun_one(test_empno in emp.empno%type) return varchar2 
    as
    test_ename emp.ename%type;
    begin
           select ename into test_ename from emp where empno = test_empno;       
           return test_ename;
    end;

    //調用方式
    declare
           str varchar2(20);
    begin
           str := fun_one(7369);
           dbms_output.put_line(str);
    end;

5)有輸入輸出的參數函數

    create or replace function fun_get_sal(test_empno in emp.empno%type,test_name out emp.ename%type) return number
    as
    test_sal emp.sal%type;
    begin
             select ename,sal into test_name,test_sal from emp where empno = test_empno;
             dbms_output.put_line(test_name);
             return test_sal;
    end;

    declare
    p_sal emp.sal%type;
    p_ename emp.ename%type;
    begin
          p_sal := fun_get_sal(7499,p_ename);
          dbms_output.put_line(p_sal);
    end;


6)查詢所有的存儲函數
    select * from user_procedures;

7)查看存儲函數具體內容
    select * from user_source;

8)刪除存儲函數
    drop function 函數名;

三十九、程序包

1)什么是程序包
    包(Package)是一組相關過程、函數、變量、常量、類型和游標等PL/SQL程序設計元素的組合。包具有面向對象設計的特點,是對這些PL/SQL程序設計元素的封裝。

2)程序包組成
    包的包括兩部分:定義一個包(包頭)、實現一個包(包體);只有當定義包后才能實現包體.其中包體中的函數名與過程名須和包頭中定義的函數、過程一樣。

3)程序包注意
    1、包和包體必須有相同的名字;
    2、包的開始沒有begin語句,與存儲過程和函數不同;
    3、在包頭部分定義函數和過程的名稱和參數,具體實現在包體中定義;
    4、在包體內聲明常量、變量、類型定義、異常、及游標時不使用declare;
    5、包體內的過程和函數的定義不要create or replace語句;
    6、包定義和包體兩者分離。

4)程序包有什么用
    通過包可以分類管理存儲過程和函數。

5)創建包頭語法
    create or replace package 包名 is|as
           --公共類型和對象
           --子程序說明
    end;

    create or replace package 包名 as
           --私有自定義類型(包內可用)
           type 類型名 is 類型;
           --私有常量(包內可用)
           常量名 constant 類型 := 值;
           --私有變量(包內可用)
           常量名 類型;
           --存儲過程
           procedure 
           --存儲函數
           function
    end;

6)創建包頭

    create or replace package p_one_test as
           --定義存儲過程
           procedure pro_pro_one(p_empno emp.empno%type); 
           --定義函數
           function pro_fun_one(p_empno emp.empno%type) return varchar2;
    end;


7)實現包體
    create or replace package body p_one_test as

           test_ename emp.ename%type;


           procedure pro_pro_one(p_empno emp.empno%type) as
           begin
                 select ename into test_ename from emp where empno = p_empno;
                 dbms_output.put_line(test_ename);
           end;


           function pro_fun_one(p_empno emp.empno%type) return varchar2 as
           begin
                 select ename into test_ename from emp where empno =  p_empno;
                 return test_ename;
           end;

    end;

8)調用包
    declare
           test_ename emp.ename%type;
    begin
           p_one_test.pro_pro_one(7369);
           test_ename := p_one_test.pro_fun_one(7369);
           dbms_output.put_line(test_ename);
    end;

9)刪除包
    drop package 包名;

四十、觸發器

1)什么是觸發器
    觸發器在數據庫里以獨立的對象存儲,它與存儲過程和函數不同的是,存儲過程與函數需要用戶顯示調用才執行,而觸發器是由一個事件來啟動運行。即觸發器是當某個事件發生時自動地隱式運行。并且,觸發器不能接收參數。

2)觸發器語法
    create or replace trigger 觸發器名
    before|after
    insert|update|delete [of 列名] on 表名
    [for each row]
    <pl/sql塊>

    關鍵字"before"在操作完成前觸發;"after"則是在操作完成后觸發;
    關鍵字"for each row"指定觸發器每行觸發一次,若不指定則為表級觸發器.
    關鍵字"of <列名>" 不寫表示對整個表的所有列.
    pl/sql塊中不能使用commit;

    :new --為一個引用最新的行值;
    :old --為一個引用以前的行值; 
    這些變量只有在使用了關鍵字 "for each row"時才存在.
    且update語句兩個都有,
    而insert只有:new ,
    delect 只有:old;

3)行級觸發器

4)表級觸發器

5)開啟禁用觸發器

四十一、數據字典

    

四十二、閃回


四十三、數據庫備份與恢復


四十四、數據庫性能優化


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容