1. 程式人生 > 資訊 >《人類一敗塗地》發售 5 年,銷量突破 3000 萬份

《人類一敗塗地》發售 5 年,銷量突破 3000 萬份

1、Orcale

1.1 Oracle第一天

1.1.1 今日內容

1. orcale的準備:
    1. orcale介紹
    2. orcale安裝
    3. orcale體系結構
2. orcale 理解:
    1. 建立表空間
    2. 使用者
    3. orcale資料型別應用
    4. 表的管理
    5. Scott使用者下的表結構
3. orcale 應用:
    1. 單行函式
    2. 多行函式
    3. 分組統計
    4. 多表查詢
    5. 子查詢
    6. Rownum與分頁查詢

1.1.2 orcale的準備

1
. orcale的介紹: * orcale資料庫系統是ORCALE公司(甲骨文)提供的以分散式資料庫為核心的一組軟體產品,是目前最流行的客戶/伺服器或B/S體系結構的資料庫之一。比如SilverStream就是基於資料庫的一組中介軟體。 * 作為一個通用的資料庫系統,它具有完整的資料管理功能;作為一個關係資料庫,它是一個完備關係的產品;作為分散式資料庫它實現了分散式處理功能。 2. orcale安裝:【在學習過程中安裝orcale儘可能安裝在虛擬機器中,因為它的解除安裝和安裝很麻煩,動不動就需要重灌系統】 1. 安裝虛擬機器 2. 安裝xp系統 3. 將orcale裝入虛擬機器的xp系統中
4. 將orcale的遠端連線軟體放入不帶中文空格括號的路徑中連線 5. 將圖形化介面進行連線設定 6. [具體請參考文件或網上搜索]

1.1.3 orcale的理解

1. 資料庫:Oracle 資料庫是資料的物理儲存。這就包括(資料檔案ORA或者 DBF、控制檔案、聯機日誌、引數檔案)。其實Oracle 資料庫概念和其它資料庫不一樣,這裡的資料庫是一個作業系統只有一個庫。可以看作是Oracle 就只有一個大資料庫。

2. 例項:一個Orcale例項(Orcale Instance)有一系列的後臺程序(Backguound Processes)和記憶體結構(Memory Structures)組成,一個數據庫可以有n個例項

3. 使用者:使用者是在例項下建立的。不同例項可以建立相同名字的使用者。 4. 表空間:表空間是 Oracle 對物理資料庫上相關資料檔案(ORA或者 DBF 檔案)的邏輯對映。一個數據庫在邏輯上被劃分成一到若干個表空間,每個表空間包含了在邏輯上相關聯的一組結構。每個資料庫至少有一個表空間(稱之為system表空間)。每個表空間由同一磁碟上的一個或多個檔案組成,這些檔案叫資料檔案(datafile)。一個數據檔案只能屬於一個表空間。 5. 資料檔案(bdf/ora):資料檔案時資料庫的物理儲存單位。資料庫的資料是儲存在表空間的,真正是在某一個或者多個數據檔案中。而一個表空間可以由一個或者多個數據檔案組成,一個數據檔案只能屬於一個表空間。一旦資料檔案被加入到某個表空間後,就不能刪除這個檔案,如果要刪除某個資料檔案,只能刪除其所屬於的表空間才行; * 表的資料,是有使用者放入某一個表空間的,而這個表空間會隨機把這些表資料放到一個或者多個數據檔案彙總。 5. 體系結構:例項>表空間=使用者>1. 一個例項相當於一個程序 2. 表空間是一個比較大的管理範圍,下面有使用者,使用者下面有表;我們建立表的時候只能在使用者下建立表,所以必須要先指定表在哪個表空間; * 即 表空間-> 使用者 ->3. 一個例項對應多個表空間: 1:N * 多個使用者屬於一個表空間: N:1 * 表空間是邏輯單位 * 一個表空間可以儲存多個物理儲存檔案 * 一個表空間也可以儲存多個使用者 6. 建立表空間: * 一個數據庫下可以建立多個表空間,一個表空間可以建立多個使用者、一個使用者下可以建立多個表。 * 示例: * create tablespace itcast * datafile 'c:\itcast.dbf' * size 100m * autoextend on * next 10m * 解釋: * itcast 表空間名稱 * datafile 指定表空間的對應的資料檔案 * size 後定義的是表空間的初始大小 * autoextend on 自動增長,當表空間儲存都佔滿時,自動增長 * next 後指定的是一次自動增長的大小 7. orcale資料型別 1. 字串: * varchar :不可變字串 * varchar2: 可變字串 2. number* number(n)表示一個整數,長度是n * number(m,n)表示一個小數,總長度是m,小數是n,整數是m-n 3. data: * 表示日期型別 4. clob: * 大物件,表示大文字資料型別,可存4G 5. bolb: * 表示二進位制資料型別,可存4G

1.1.4 orcale的應用

1. 常用程式碼:
        --建立表空間
    create tablespace itheima
    datafile 'c:\itheima.dbf'
    size 100m
    autoextend on
    next 10m;
    --刪除表空間
    drop tablespace itheima;
    
    --建立使用者
    create user itheima
    identified by itheima
    default tablespace itheima;
    
    --給使用者授權
    --oracle資料庫中常用角色
    connect--連線角色,基本角色
    resource--開發者角色
    dba--超級管理員角色
    --給itheima使用者授予dba角色
    grant dba to itheima;
    
    ---切換到itheima使用者下
    
    ---建立一個person表
    create table person(
           pid number(20),
           pname varchar2(10)
    );
    
    ---修改表結構
    ---新增一列
    alter table person add (gender number(1));
    ---修改列型別
    alter table person modify gender char(1);
    ---修改列名稱
    alter table person rename column gender to sex;
    ---刪除一列
    alter table person drop column sex;
    
    ---查詢表中記錄
    select * from person;
    ----新增一條記錄
    insert into person (pid, pname) values (1, '小明');
    commit;
    ----修改一條記錄
    update person set pname = '小馬' where pid = 1;
    commit;
    
    -- 三個刪除
    -- 刪除表中全部記錄
    delete from person;
    -- 刪除表結構
    drop table person;
    -- 先刪除表,再次建立表。效果等同於刪除表中全部記錄。
    -- 在資料量的情況下,尤其在表中帶有索引的情況下,該操作效率高。
    -- 索引可以提供查詢效率,但是會影響增刪改效率。
    truncate table person;
    -- 序列不真的屬於任何一張表,但是可以邏輯和表做繫結
    -- 序列:預設從1開始,依次遞增,主要用來給主鍵賦值使用。
    create sequence s_person;
    select s_person.nextval from dual;
    
    -- 新增一條記錄
    insert into person (pid,pname) values (s_person.nextval,'小明');
    commit;
    select * from person;
    
    
    -- 剛剛安裝完orcale,scott使用者是被鎖定的,需要用有管理員許可權的賬戶進行解鎖;
    -- scott使用者,密碼tiger
    -- 解鎖scott使用者
    alter user scott account unlock;
    -- 解鎖scott使用者的密碼[此句也可以用來重置密碼]
    alter user scott identified by tiger;
    -- 切換到scott使用者下
    後面的函式均以切換到scott使用者下。因為scott使用者下有一些現成的表,可以進行學習使用;
    
    
    
    -- MGR 直屬領導,HIREDATE 入職日期  ,SAL工資,COMM年終獎 , DEPTNO部門編號,LOC部門地址
    -- GRAGE工資等級 ,
    
    -- 單行函式:作用於一行,返回一個值'
    -- 字元函式
    -- 小寫變大寫
    select upper('yes') from dual;    -- YES
    -- 大寫變小寫
    select lower('YES') from dual;    -- yes
    
    -- 數值函式
    select round(26.16,-1) from dual;    -- 四捨五入,後面的引數表示保留的位數  正數是往後算,負數是往前算,以'.'開始
    select trunc(56.16,-1) from dual;    -- 直接擷取,不再看後面位數的數字是否大於5
    select mod(10,3) from dual;   -- 求餘數     這些在java中實現很容易,所以我們儘可能的直接在java中完成,不在資料庫中進行這些操作;
    
    -- 日期函式
    -- 查詢出emp表彙總所有員工入職距離現在幾天
    select sysdate-e.hiredate from emp e;
    -- 算出明天此刻
    select sysdate+1 form dual;
    -- 查詢出emp表中所有員工入職距離現在幾月
    select months_between(sysdate,e.hiredate) from emp e;
    -- 查詢emp表中所有員工入職距離現在幾年;
    select months_between(sysdate,e.hiredate)/12 from emp e;
    -- 查詢出emp表中所有員工入職距離現在幾周;
    select round((sysdate-e.hiredate)/7) from emp e;
    -- 轉換函式
    -- 日期轉字串
    select to_char(sysdate,'yyyy-mm-dd hh:mi:ss') from dual;
    -- 24小時制轉換
    select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
    -- 字串轉日期       [雖然它的結果可能跟上面的一樣,但上面的型別是字串,它的型別是日期型別,結果一樣但是型別不一樣]
    select to_date('2018-6-7 16:39:56','fm yyyy-mm-dd hh24:mi:ss') from dual;
    -- 通用函式
    -- 算出emp表中所有員工的年薪
    -- 獎金裡面有null值,如果null值和任意數字做算數運算,結果都是null;
    -- 可以使用val來處理null
    select e.sal*12+nvl(e.comm,0) from emp e;
    
    -- 條件表示式[這兩個,一個等值一個範圍是mysql和orcale通用寫法;]
    
    -- 等值判斷
    -- 給emp表中員工起中文名 
    select e.ename,
           case e.ename
             when 'SMTTH' then '曹賊'
               when 'ALLEN' then '大耳賊'
                 when 'WARD' then '諸葛小兒'
                   else '無名'
                     end
    from emp e;
    -- 範圍判斷
    -- 判斷emp表中員工工資,如果高於3000顯示高收入,如果高於1500低於3000顯示中收入,如果低於1500,顯示低收入
    select e.sal,
           case e.sal
             when e.sal>3000 then '高收入'
               when e.sal>1500 then '中等收入'
                 else '低收入'
                   end
    from emp e;
    
    -- orcale專用條件表示式
    select e.ename,
           decode(e.ename,
           'SMITH','曹賊',
           'ALLEN','大耳賊',
           'WARD','諸葛小兒',
           '無名')"中文名" from emp;    -- 這裡的中文名是將該列的列名改為'中文名'
    
    
    
    
    -- 列名使用中文可以使用雙引號或者不帶引號,如果用單引號會報錯。
    -- 使用條件表示式一般用通用方式而儘可能少用專用條件表示式,因為使用通用表示式使程式碼可重用性提高;
    -- 多行函式【聚合函式】:作用於多行,返回一個值;
    -- 引數1相當於直接輸入主鍵,推薦寫count(1)
    select count(1) from emp;    -- 查詢總數量
    select sum(sal) from emp;    -- 工資總和
    select max(sal) from emp;    -- 最大工資
    select min(sal) from emp;      -- 最低工資
    select avg(sal) from emp;      -- 平均工資
    -- 分號是一次查詢的結束,如果有多條查詢語句,每句查詢語句末尾應該新增分號;
    
    
    -- 分組查詢[工作中常用]
    -- 查詢出每個部門的平均工資
    -- 分組查詢中,出現在group by後面的原始列,才能出現在select後面
    -- 沒有出現在group by後面的列,想在select 後面,必須加上聚合函式。
    select e.deptno,avg(e.sal)   -- e.ename【這裡就不能加上e.ename,因為沒有出現在group by,並且邏輯上也不對】
    from emp e 
    group by e.deptno;
    
    -- 查詢出平均工資高於2000的部門資訊
    -- 所有條件都不能使用別名來判斷。
    -- 因為所有的查詢都有先後順序,where條件優先於select進行,where條件下起了別名,而系統就不知道別名是什麼意思了,因為別名代表的資料庫名字的內容還未執行;
    select e.deptno, avg(e.sal) asal
    from emp e
    group by e.deptno
    having avg(e.sal)>2000;
    
    -- 查詢每個部門工資高於800的員工的平均工資
    -- where是過濾分組前的資料,having是過濾分組後的資料
    -- 表現形式:where必須在group by之前,having是在group by之後
    -- 查詢出每個部門工資高於800的員工的平均工資
    -- 然後再查詢出平均工資高於2000的部門
    select e.deptno,avg(e.sal) asal
    from emp e
    where e.sal>800
    group by e.deptno
    having avg(e.sal)>2000;
    
    
    -- 執行順序
    -- 分組[having]-排序   排序是在分組的後面
    
    
    -- 多表查詢中的一些概念
    -- 笛卡爾積: 兩張表的所有記錄互相相乘
    -- 它沒有多大的實際意義,因為很多資料是沒有用的
    select * from emp e, dept d;
    
    -- 如何過濾掉沒用的資料,顯示有用的資料,可以使用'等值連線'
    -- 等值連線
    select * 
    form emp e, dept d
    where e.deptno=d.deptno;
    -- 內連線
    select * 
    from emp e inner join dept d
     on e.deptno=d.deptno;
    
    -- 推薦大家使用等值連線,但是內連線也要學習,方便看別人的。等值連線是在內連線的基礎上建立起來的;
    
    
    
    -- 查詢出所有部門,以及部門下的員工資訊,可以使用外連線
    -- 外連線 ,分為左外連線和右外連線
    -- 右外連線
     select * 
     from emp e right join dept d
     on e.deptno=d.deptno;
    
    -- 查詢所有員工資訊,以及員工所屬部門
    -- 左外連線
    select * 
    from emp e left join dept d
    on e.deptno=d.deptno;
    
    -- orcale 中專用外連線
    -- 左外連線
    select * 
    form emp e, dept d
    where e.deptno(+)=d.deptno;
    -- 右外連線
    select * 
    form emp e, dept d
    where e.deptno=d.deptno(+);
    
    
    
    
    -- 查詢出員工姓名,員工領導姓名         [這裡的員工表和領導表是同一張表]
    -- 自連線:自連線其實就是站在不同的角度把一張表看成多張表;
    select e1.ename,e2.ename 
    from emp e1, emp e2
    where e1.mgr=e2.emp.empno;   -- e1表的所有領導都是e2表的所有員工,這就表示了,e1表示員工表,e2是領導表
    
    -- 查詢出員工姓名,員工部門名稱,員工領導姓名,員工領導部門名稱
    select e1.ename,e2.ename
    form emp e1, emp e2,dept d1,dept d2
    where e1.mgr= e2.empno
    and e1.deptno=d1.deptno; 
    and e2.deptno=d2.deptno;
    
    -- 我們在工作中更多的是寫語句,實現功能,各種sql,所以sql與我們的開發中聯絡是很緊密的;
    
    
    -- 子查詢:在一條sql語句中嵌套了另外一條sql語句
    -- 子查詢返回一個值
    -- 查詢出工資和SCOTT一樣的員工資訊,這裡ename不是主鍵不能保證非空唯一,如果查詢出來是一個集合,就會出問題了,最好是以主鍵為條件進行查詢
    select * from emp where sal =
    (select sal from emp where ename='SCOTT');
    -- 子查詢返回一個集合
    -- 查詢出員工工資和10號部門任意員工一樣的員工資訊
    select * from emp where sal in 
    (select sal from emp where deptno =10);
    -- 子查詢返回一張表
    -- 查詢出每個部門最低工資,和最低工資員工姓名和該員工所在部門名稱
    -- 1.先查詢出每個部門的最低工資
    select deptno,min(sal)
    from emp
    group by deptno;
    -- 2. 三表聯查,得到最終結果
    select t.deptno,t.msal,e.ename,d.dname
    from (select deptno,min(sal) msal
         from emp
         group by deptno ) t,emp e,dept d
    where t.deptno= e.deptno
    and t.msal=e.sal
    and e.deptno=d.deptno;
    
    
    -- orcale 分頁查詢 一般要使用三層巢狀;
    -- orcale中的分頁
    -- rownum行號:當我們做select操作的時候,
    -- 每查詢出一行記錄,就會在該行上加一個行號,
    -- 行號從1開始,依次遞增,不能跳著走。
    -- emp表工資倒序排列後,每頁五條記錄,查詢第二頁。
    select rownum* from emp e rownum <4 order by e.sal desc;
    -- select 先執行,然後才執行order by,順序會亂,因為排序操作會影響rownum的順序
    -- 解決辦法:先排序再加行號,使用巢狀查詢;
    select rownum, * from(
    select ruwnum, e.* from emp e order by e.sal desc);
    -- 如果要去掉裡面的亂的行號,子查詢直接不查詢裡面的rownum即可。
    
    -- emp表工資倒敘排列後,每頁五條記錄,查詢第二頁
    select * from(
    select rownum rn,e.* from(
    select * from emp order by sal desc 
    ) e where rownum <11
    ) tt where rn >5;
    
    
    -- rownum 行號不能寫上大於一個正數;行號大於一個正數可以使用巢狀,並且給它一個別名,即可進行條件限制;
    -- orcale中所有的分頁查詢都是巢狀兩個固定的查詢語句,裡面可以新增無數個select查詢語句進行篩選;該格式記死即可;

2. 注意的地方:
    1. 序列:
        1. [orcale註解的自增問題]* mysql有自增功能,但orcale沒有自增,所以每次傳入資料的時候,必須傳入一個id進去;但是使用者註冊不可能自己傳入id,所以需要一個序列,它是orcale的一個物件,主要解決orcale沒有自增的問題;        
            * 序列是orcale提供的用於產生一系列唯一數字的資料庫物件,它可以用於做主鍵[主鍵唯一]* 作用:做主鍵
                * create sequence 序列名稱    [建立序列]
                * nextval  返回序列的下一值 [寫一個序列,寫一個下一值,相當於自增]
                * currval 返回序列的當前值    
            * 注意:當我們在剛建立序列後,無法提取當前值,只能先提取下一個值的時候才能取值;
        2. 常用:
            * increament by n : 每次跳過n
            * start with n : 從n開始
3. 虛擬機器內的橋接,net,和主機模式
    * 橋接:區域網
    * 主機:只能和主機通訊
    * nat,也可以聯網

1.2 Oracle第二天

1.2.1 檢視

1.語句:
    -- 查詢語句建立表
    create table emp as select * from scott.emp;
    select * from emp;
    -- 建立檢視[必須有dba許可權]
    create view v_emp as select ename, job from emp;
    -- 查詢檢視
    select * from v_emp;
    -- 修改檢視[不推薦]
    update v_emp set job='CLERK' where ename='ALLEN';
    -- 建立只讀檢視
    create view v_empl as select ename, job from emp with read only;
2. 檢視的作用?
    -- 第一:檢視可以遮蔽掉一些敏感欄位
    -- 第二:保證總部和分部資料及時統一;[檢視沒有資料,資料是從總部獲取的,當總部修改了後,分部就立即修改了]

1.2.2 索引

1. 索引的概念:索引就是在表的列上構建一個二叉樹,達到大幅度提高查詢效率的目的,但是索引會影響增刪改的效率
2. 單列索引
    -- 建立單列索引
    create index idx_ename on emp(ename);
    -- 單列索引觸發規則,條件必須是索引列中的原始值
    -- 單行函式,模糊查詢,都會影響索引的觸發
    select * from emp where ename='SCOTT';
3. 複合索引
    -- 建立複合索引
    create index idx_enamejob on emp(ename,job);
    -- 如果要觸發複合索引,必須包含有優先檢索列中的原始值
    select * from emp where ename='SCOTT' and job='xx';  -- 觸發複合索引
    select * from emp where ename='SCOTT' or job='xx'; --不觸發索引[一個觸發,一個不觸發,那麼就是不觸發索引了]
    select * from emp where ename='SCOTT';  -- 觸發單列索引。 

1.2.3 pl/sql程式語言

1. 概述:
    -- pl /sql 程式語言
    -- pl/sql 程式語言是對sql語言的擴充套件,使得sql語言具有過程化程式設計的特性。
    -- pl/sql 變成語言比一般的過程化程式語言,更加靈活高效。
    -- pl/sql程式語言主要用來編寫儲存過程和儲存函式等。

2. 宣告方法
-- 賦值操作可以使用:= 也可以使用查詢語句賦值
    declare
        i number(2):=10;
        s varchar2(10):='小明';
        ena emp.ename%type;          -- 引用型變數
        emprow emp%rowtype;            -- 記錄型變數  【查詢一行的記錄】    
    begin
        dbms_output.put_line(i);
        dbms_output.put_line(s);
        select ename into ena form emp where empno=7788;    
        dbms_output.put_line(ena);
        select * into emprow form emp where empno=7788;
        dbms_output.put_line(emprow.ename || '的工作為'    || emprow.job);            //在orcale中連線符不是+ ,而是||
    end;


3. pl/sql中的if判斷
    -- 輸入小於18的數字,輸出未成年
    -- 輸入大於18 小於40的數字,輸出中年人
    -- 輸入大於40的數字,輸出老年人
    
    declare
        i number(3):=&ii;
    begin 
        if i<18 then
            dbms_output.put_line('未成年');
        elsif i<40 then
            dbms_output.put_line('中年人');
        else
            dbms_output.put_line('老年人');
        end if;
    end;


4. pl/sql中的loop迴圈
    1. 用三種方式輸出1到10 十個數字
        1. while迴圈
            declare
                i number(2):=1;
            begin
                while i<22 loop
                    dbms_output.put_line(i);
                    i:=i+1;
                end loop;
            end;


        2. exit 迴圈                //工作中用的多,掌握
            declare
                i number(2):=1;
            begin
                loop
                    exit when i>10;
                    i:i+1;
                end loop;
            end;


        3. for迴圈
        
            declare
            
            begin
                for i in 1..10 loop
                    dbms_output.put_line(i);
                end loop;
            end;


5. 遊標:可以存放多個物件,多行記錄。
    -- 輸出emp表中所有員工的姓名
        declare
            cursor cl is select * from emp;
            emprow emp%rowtype
        begin
            open c1;
                loop
                    fetch c1 into emprow;
                    exit when c1%notfound;
                    dbms_output.put_line(emprow.ename);
                end loop;
            close c1;
        end;

    -- 給指定部門員工漲工資
        declare
            cursor c2(eno emp.deptno%type) is select empno from emp where deptno=eno;
            en emp.empno%type;
        begin
            open c2(10);
                loop 
                    fetch c2 into en; 
                    exit when c2%notfound;
                    update emp set sal=sal+100 where empno=en;
                    commit;
                end loop;
            close c2;
        end;
    
    -- 查詢10號部門員工資訊
        select * from emp where deptno =10;

1.2.4 儲存過程

1.概述:
    * 儲存過程:儲存過程就是提前已經編譯好的一段pl/sql語言,放置在資料庫端,可以直接被呼叫。這一段pl/sql一般都是固定步驟的業務。   
    * 不能寫太複雜的業務,不然維護起來會很麻煩;

2. 建立儲存過程的語法:
    create [or replace] procedure 過程名[(引數名 in/out 資料型別)]
    as
    begin
        PLSQL子程式體;
    end;

  或者
    create [or repalece]procedure 過程名[(引數名 in/out 資料型別)]
    is
    begin
        PLSQL子程式體;
    end 過程名;

3.示例:
    -- 給指定員工漲100塊錢
        create or replace procedure pl(eno emp.empno%type)    -- 寫上replace如果有其他的同名字的該程式碼可以覆蓋,建議加上;
        is 
        
        begin
            update emp set sal=sal+100 where empno=eno;
            commit;
        end;
        
        select * from emp where empno=7788
    -- 測試p1 
        declare
        
        begin
            p1(7788);
        end;

    -- orcale語法嚴格,分號也必須加,不然會報錯;
    -- 建立了儲存過程的語句,無論關機後重啟開啟軟體,都能在Procedures目錄下找到該儲存過程的檔案;

1.2.5 儲存函式

1. 語法:
    create or replace function 函式名(Name in type, Name in type,...)return 資料型別 is 結果變數 資料型別;
    begin 
    return(結果變數);
    end 函式名;

    -- 通過儲存函式實現計算,指定員工的年薪
    -- 儲存過程和儲存函式的引數都不能帶長度
    -- 儲存函式放在Functions目錄下
    -- 儲存函式的返回值型別不能帶長度
2.示例:
    create or replace function f_yearsql(eno emp.empno%type) return number
    is
        s number(10);
    begin
        select sal*12+nvl(comm,0) into s from emp where empno=eno;
        return s;
    end;

3. 測試f_yearsal
    -- 儲存函式在呼叫的時候,返回值需要接收
    declare
        s number(10);
    begin
        s:=f_yearsal(7788)
        dbms_output.put_line(s);
    end;

4. out型別引數如何使用
    -- 使用儲存過程來算年薪
    create or replace procedure p_yearsal(eno emp.empno%type, yearsal out number)
    is
        s number(10);
        c emp.comm%type;
    begin
        select sal*12, nvl(comm,0) into s,c from emp where empno=eno;
        yearsal:=s+c;
    end;

5. 測試p_yearsal(7788,yearsal);
    declare
        yearsal number(10);
    begin
        p_yearsal(7788,yearsal);
        dbms_output.put_line(yearsal);
    end;

-- in和out型別的引數的區別是什麼?
-- 凡是涉及到into查詢語句賦值或者 := 賦值操作的引數,都必須使用out來修飾;



-- 儲存過程和儲存函式的區別?
-- 語法區別:1.關鍵字不一樣  2. 儲存函式比儲存過程多了兩個return
-- 本質區別:儲存函式有返回值,而儲存過程沒有返回值
-- 如果儲存過程想實現有返回值的業務,我們就必須使用out型別的引數
-- 即便是儲存過程使用了out型別的引數,其本質也不是真的有了返回值
-- 而是在儲存過程內部給out型別引數賦值,在執行完畢後,我們直接其返回值操作。

6.自定義函式
    -- 我們可以使用儲存函式有返回值的特性,來自定義函式。
    -- 而儲存過程不能用來自定義函式。 
    -- 案例需求:查詢出員工姓名,員工所在部門名稱。
    -- 案例準備工作:把scott使用者下的dept表複製到當前使用者下
    crate table dept as select * from soctt.dept;
    -- 使用傳統方式來實現案例需求
    select 
    from emp e; dept d
    where e.deptno=d.deptno;
    
    -- 使用儲存函式來是西安提供一個部門編號,輸出一個部門名稱。
    create or replace function fdna(dno dept.deptno%type) return dept.dname%type
    is 
        dna dept.dname%type;
    begin
        select dname into dna from dept where deptno=dno;
        return dna;
    end;
    
    -- 使用fdna儲存函式來實現案例需求
    select e.ename,fdna(e.deptno)        -- 這裡fdna呼叫了上面儲存過程方法
    from emp e;
    
    -- 儲存過程和儲存函式相當於java中的方法,儲存過程用來增刪改,儲存函式可以用來做查詢;

1.2.6 觸發器

1.概述:
    -- 觸發器,就是指定一個規則,在我們做增刪改操作的時候,只要滿足該規則,自動觸發,無需呼叫。   查詢的時候不會呼叫到觸發器;
    -- 語句級觸發器:不包含有for each row的觸發器
    -- 行級觸發器:包含有for each row 的就是行級觸發器
    --- 加for each row 為了使用 :old 或者 :new 物件或者一行記錄。
    -- 資料中的一行資料對應java中的物件 
    
    -- insert 的 :old 是所有欄位為null,:new 之後就有了新的資料
    -- Update 的     :old 是更新以前該行的值, :new 是更新後的值
    -- delete 的 :old 是刪除之前該行的值, :new 是所有欄位都為null
2.示例:
    1. 語句級觸發器:
    -- 插入一條記錄,輸入一個新員工入職        //觸發器示例
        create or replace trigger t1 
        after
        insert
        on person
        declare
        
        begin
            dbms_output.put_line('一個新員工入職');
        end;

    
    -- 觸發t1
        insert into person values(1,'小紅');
        commit;
    
    -- 查詢
        select * from person;


    2. 行級觸發器
    -- 不能給員工降薪
    -- raise_application_error()
        create or replace tigger t2
        before 
        update
        on emp
        for each row
        declare
        
        begin
            if:old.sal>:new.sal then
                raise_application_error(-200001,'不能給員工降薪')
            end if;   
        end;
    
    
    -- 觸發t2
        update emp set sal=sal-1 where empno =7788;
        commit-- 查詢    
        select * form emp where empno=7788;


3. 觸發器實現主鍵自增。[行級觸發器]
    -- 分析:在使用者做插入操作之前,拿到即將插入的資料。
    -- 給該資料中的主鍵列賦值。
        create or replace tigger auid
        before
        insert
        on person
        for each row
        declare
        
        begin
            select s_person.nextval into :new.pid from dual;
        end;
    
    -- 查詢person表資料
        select * from person;
    -- 使用auid實現主鍵自增
        insert into person (pname) values ('a');
        commit;




4. 使用java呼叫orcale中的儲存過程和儲存函式
    -- orcale10g  ojbdc14.jar
    -- orcalel11g  ojdbc6.jar
    
    
    示例:
        1. 建立一個maven工程   gid:com.itheima    aid:jdbc_orcale
        2. Maven projects need to be imported?[是否自動匯入]  ->Enable Auto-Import  確定自動匯入
        3. pom.xml匯入角標:[ojdbc14/runtime,junit/test]
        4. test.java.com.itheima.orcale.OrcaleDame:建立該類:
            * public class OrcaleDemo{
            * @Test
            * public void javaCa11Orcale() throws Exception{
            * //載入資料庫驅動
            * Class.forName("orcale.jdbc.driver.OrcaleDriver")
            * //得到connection連線
            * Connection connection=DriverManager.getConnection("jdbc:orcale:thin:@192.168.88.6:1521:orcale",scott,tiger)
            * //得到預編譯的Statement物件
            * CallableStatement pstm=connection.prepareCall("{call p_yearsal(?,?)}");
            * //給引數賦值
            * pstm.setObject(1,7788);
            * pstm.registerOutParameter(2,OracleType.NUMBER);
            * //執行資料庫查詢操作
            * pstm.execute();
            * //輸出結果
            * System.out.println(pstm.getObject("2"));
            * pstm.close();
            * }

1.2.7 java呼叫儲存過程和儲存函式

1.介面:CallableStatement
    *  {?=call<procedure-name>[(<arg1>,<arg2>,...)]}             呼叫儲存函式使用
    *  {call<procedure-name>[(<arg1>,<arg2>,...)]}         呼叫儲存過程使用。
    
2. 示例:
    * public class OrcaleDemo{
    * @Test
    * public void javaCa11Orcale() throws Exception{
    * //載入資料庫驅動
    * Class.forName("orcale.jdbc.driver.OrcaleDriver")
    * //得到connection連線
    * Connection connection=DriverManager.getConnection("jdbc:orcale:thin:@192.168.88.6:1521:orcale",scott,tiger)
    * //得到預編譯的Statement物件
    * PreparedStatement pstm=connection.prepareStatement("select * from emp where empno=?");
    * //給引數賦值
    * pstm.setObject(1,7788);
    * //執行資料庫查詢操作
    * ResultSet rs=pstm.executeQuery();
    * //輸出結果
    * while(rs.next){
    * System.out.println(rs.getString("ename"));
    * }
    * }