<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      java常用數(shù)據(jù)庫oracle---深入理解oracle的實際運用

      一、Oracle概念
      oracle數(shù)據(jù)可系統(tǒng)是美國oracle(甲骨文)公司提供的以分布式數(shù)據(jù)庫為核心的一組軟件產(chǎn)品,是目前最流行的客戶/服務(wù)器或B/S體系結(jié)構(gòu)的數(shù)據(jù)庫之一,oracle數(shù)據(jù)庫時目前世界上使用最為廣泛的數(shù)據(jù)庫管理系統(tǒng),作為一個通用的數(shù)據(jù)庫系統(tǒng),它具有完善的數(shù)據(jù)庫管理功能,是關(guān)系型數(shù)據(jù)庫,比mysql更為龐大,在現(xiàn)行的關(guān)系型數(shù)據(jù)庫中排名第一(oracle、mysql、SqlServer),時間是最為精確的。

      二、Oracle的安裝
      安裝教程

      三、Oracle數(shù)據(jù)庫的體系結(jié)構(gòu)
      1、數(shù)據(jù)庫database
      Oracle數(shù)據(jù)庫是數(shù)據(jù)的物理儲存,這就包括(數(shù)據(jù)文件ORA或者DBF、控制文件、聯(lián)機日志、參數(shù)文件)。其實Oracle數(shù)據(jù)庫的概念和其他數(shù)據(jù)庫不一樣,這里的數(shù)據(jù)庫時一個操作系統(tǒng)只有一個庫,可以看做Oracle就只有一個大數(shù)據(jù)庫。

      2、實例
      一個數(shù)據(jù)庫可以有n個實例,有一系列的后臺進程和內(nèi)存結(jié)構(gòu)組成。

      3、數(shù)據(jù)文件dbf
      是數(shù)據(jù)庫的物理儲存單位,數(shù)據(jù)庫的數(shù)據(jù)是儲存在表空間中的,真正是在某一個或者多個數(shù)據(jù)文件中,而一個表空間可以由一個或多個數(shù)據(jù)文件組成,一個數(shù)據(jù)文件只能屬于一個表空間,一旦數(shù)據(jù)文件被加入到某個表空間后,就不能刪除這個文件,如果要刪除某個數(shù)據(jù)文件,只能刪除其所屬于的表空間才行。

      4、表空間
      表空間是Oracle對物理數(shù)據(jù)庫上相關(guān)數(shù)據(jù)文件的邏輯映射,一個數(shù)據(jù)庫在邏輯上被劃分成一到若干個表空間,每個表空間包含了在邏輯上相關(guān)聯(lián)的一組結(jié)構(gòu),每個數(shù)據(jù)庫至少有一個表空間(稱之為system表空間)

      每個表空間由同一磁盤上的一個或多個文件組成,這些文件叫數(shù)據(jù)文件,一個數(shù)據(jù)文件只能屬于一個表空間。

      5、用戶
      用戶是在實例下建立的,不同實例中可以建相同名字的用戶,表的數(shù)據(jù)是由用戶放入某一個表空間的,而這個表龍劍會隨機把這些表數(shù)據(jù)進行管理和存放的,但是表不是由表空間去查詢的,而是由用戶去查詢。

      6、SCOTT和HR用戶
      是Oracle幫我們建好的測試賬戶,Scott賬戶常用,里面有emp、dept表等。

      四、Oracle和MYSQL的差別
      1、新建項目的方式

      MYSQL : 創(chuàng)建一個數(shù)據(jù)庫,創(chuàng)建相應(yīng)的表

      2、Oracle是多用戶的, MYSQL是多數(shù)據(jù)庫的

      3、Oracle安全級別要高,MYSQL開源免費

      五、基本查詢
      1、SQL概念
      結(jié)構(gòu)化查詢語言

      2、SQL分類
      DDL : 數(shù)據(jù)定義語言 create alter drop truncate
      DML : 數(shù)據(jù)操縱語言 insert update delete
      DCL : 數(shù)據(jù)控制語言 安全 授權(quán) grant revoke
      DQL : 數(shù)據(jù)查詢語言 select from子句 where子句

      在oracle中將DQL放入DML中,多了TCL:事務(wù)控制語言 commit、rollback

      3、Oracle中的數(shù)據(jù)字典
      所謂數(shù)據(jù)字典就是編寫sql語句,全選可以一次性執(zhí)行不報錯

      /* 1.刪除數(shù)據(jù)對象 */
      -- 刪除數(shù)據(jù)表
      drop table t_reply;
      drop table t_user;
      -- 刪除序列
      drop sequence sq_user;
      drop sequence sq_reply;

      /* 2.創(chuàng)建數(shù)據(jù)對象 */
      -- 創(chuàng)建數(shù)據(jù)表
      create table t_user(
      u_id number(4) primary key,
      u_userName varchar2(40) unique not null,
      u_password varchar2(50) not null,
      u_gender number(1) check(u_gender in (0,1,2)),
      u_age number(3) check(u_age between 12 and 120),
      u_registeTime date not null
      );
      create table t_reply(
      r_id number(10) primary key,
      r_content varchar2(500) not null,
      r_userId number(4) not null,
      foreign key(r_userId) references t_user(u_id)
      );
      -- 創(chuàng)建序列
      create sequence sq_user start with 1001;
      create sequence sq_reply start with 10000001;

      /* 3.添加測試數(shù)據(jù) /
      -- 處理全新的數(shù)據(jù)表和全新的序列在使用時取不到初始值的問題
      insert into t_user values
      (1, '1', '1', 1, 25, sysdate);
      insert into t_reply values
      (1, '1', 1);
      delete from t_reply;
      delete from t_user;
      commit;
      /
      insert into t_user values
      (1000, 'owner', '9999', 1, 25, sysdate);
      insert into t_reply values
      (10000000, '人員召集...', 1000);*/

      -- 添加數(shù)據(jù)
      insert into t_user values
      (sq_user.nextval, 'admin', '9999', 1, 25, sysdate);
      insert into t_reply values
      (sq_reply.nextval, '系統(tǒng)1.0上線...', sq_user.currval);

      /* 4.提交 */
      commit;

      /* 5.查詢語句 /
      /

      select * from t_user;
      select * from t_reply;
      */

      3、查詢語句的結(jié)構(gòu)
      select [列名] [*] from 表名 [where 條件] [group by 分組條件] [having 過濾] [order by 排序]

      4、偽表dual
      dual : oracle中的虛表 ,偽表, 主要是用來補齊語法結(jié)構(gòu),

      比如:select 1+1 from dual;
      注意:直接寫一個常量比寫 * 要高效
      select count(1) from emp;
      select count(*) from emp;

      5、別名查詢
      使用as 關(guān)鍵字, 可以省略,別名中不能有特殊字符或者關(guān)鍵字, 如果有就加雙引號(比如空格)

      elect ename 姓名, sal 工資 from emp;
      select ename "姓 名", sal 工資 from emp;

      6、去除重復(fù)數(shù)據(jù) distinct
      加在select和列名后面,多列去除重復(fù): 每一列都一樣才能夠算作是重復(fù)

      --單列去除重復(fù)
      select distinct job from emp;

      --多列去除重復(fù)的
      select distinct job,deptno from emp;

      7、查詢中四則運算
      需要用到偽表dual

      select 1+1 from dual;
      --查詢員工年薪 = 月薪* 12
      select sal*12 from emp;

      在Oracle 中 ,雙引號主要是別名的時候使用, 單引號是使用的值, 是字符

      8、空值處理函數(shù)
      注意: null值 , 代表不確定的 不可預(yù)知的內(nèi)容 , 不可以做四則運算

      1)mysql的空值處理
      ? ifnull(參數(shù)1, 參數(shù)2):
      ? 判斷參數(shù)1是否為null,
      ? 不為null, 則函數(shù)的結(jié)果取參數(shù)1的值
      ? 為null, 則取參數(shù)2的值
      ? if(參數(shù)1, 參數(shù)2, 參數(shù)3)
      ? 判斷參數(shù)1是否為null,
      ? 為null, 則取參數(shù)3的值
      ? 不為null, 則取參數(shù)2的值
      ? 注意if函數(shù)只能處理數(shù)值字段的空值

      SELECT e.ename 姓名,
      e.sal 底薪,
      e.comm 獎金,
      (e.sal+e.comm) 實發(fā),
      IFNULL(e.sal+e.comm, e.sal) 實發(fā)1,
      IF(e.comm, e.sal+e.comm, e.sal) 實發(fā)2
      FROM emp e;

      2)oracle的空值處理

      nvl(參數(shù)1,參數(shù)2):如果1為null,則返回2,不為null就為1

      nvl2(參數(shù)1, 參數(shù)2, 參數(shù)3)1為null,則返回,3,不為null,則返回2

      decode(需要判斷的字段,
      ? 常量值1, 結(jié)果值1,
      ? 常量值2, 結(jié)果值2,
      ? …
      ? 常量值n, 結(jié)果值n,
      ? 默認結(jié)果值
      ? )

      select e.ename 姓名,
      e.sal 底薪,
      e.comm 獎金,
      nvl(e.sal+e.comm, e.sal) 實發(fā)1,
      nvl2(e.comm, e.sal+e.comm, e.sal) 實發(fā)2,
      decode(e.comm, null, e.sal, e.sal+e.comm) 實發(fā)3
      from emp e;

      9、字符串拼接
      Oracle 特有的連接符: || 拼接
      concat(str1,str2) 函數(shù), 在mysql和Oracle中都有
      --查詢員工姓名 : 姓名:SCOTT
      select ename from emp;
      --使用拼接符
      select '姓名:' || ename from emp;

      --使用函數(shù)拼接
      select concat('姓名:',ename) from emp;

      六、條件查詢
      條件查詢就是where后面的寫法

      1、關(guān)系運算符和排序

      = = < <= != <>
      注意:不等于既可以用!=也可以用<>但是<>效率更高

      2、邏輯運算符
      and or not

      3、其它運算符
      like 模糊查詢
      in(set) 在某個集合內(nèi)
      between..and.. 在某個區(qū)間內(nèi)
      is null 判斷為空
      is not null 判斷不為空

      4、模糊查詢: like
      % 匹配多個字符

      _ 匹配單個字符

      如果有特殊字符, 需要使用escape轉(zhuǎn)義

      --查詢員工姓名中,包含%的員工信息
      select * from emp where ename like '%%%' escape '';

      select * from emp where ename like '%#%%' escape '#';

      5、排序order by
      升序: asc ascend

      降序: desc descend

      排序注意null問題 : nulls first | last指定null值顯示的位置

      同時排列多列, 用逗號隔開

      --查詢員工信息,按照獎金由高到低排序
      select * from emp order by comm desc nulls last;

      --查詢部門編號和按照工資 按照部門升序排序, 工資降序排序
      select deptno, sal from emp order by deptno asc, sal desc;

      分析函數(shù):用來處理排名并列問題

      rank——排名可并列,之后序號不會順眼(如2個第二,下一個是第三名)

      dense_rank——排名可并列,之后序號會順眼(如2個第二,下一個是第四名)

      row_number——不可并列排名

      over——添加分組條件

      partition—by——分組

      6、分組排序
      select 分組的條件,分組之后的條件 from 表名 group by 分組的條件 having 條件過濾
      在分組查詢語句的檢索內(nèi)容中, 只能出現(xiàn)分組字段和聚合函數(shù)
      sql的編寫順序:
      ? select,from,where,group by,having,order by
      sql的執(zhí)行順序:
      ? from,where,group by,having,select,order by…

      where和having的區(qū)別:

      where后面不能跟聚合函數(shù),可以接單行函數(shù)
      having是在group by之后執(zhí)行,可以接聚合函數(shù)

      --分組統(tǒng)計所有部門的平均工資,找出平均工資大于1500的部門
      select deptno,avg(sal) from emp group by deptno having avg(sal)>1500;

      --報錯,給分組之后的條件取別名的時候出錯,因為sql語句執(zhí)行的順序問題
      select deptno,avg(sal),bb from emp group by deptno having bb>1500;

      七、函數(shù)
      函數(shù): 必須要有返回值

      1、單行函數(shù)
      對某一行中的某個值進行處理

      1)數(shù)值函數(shù)

      取整

      select ceil(45.926) from dual; --46 向上取整
      select floor(45.926) from dual; --45 向下取整

      四舍五入

      round(a,b)

      b如果是正數(shù)代表取到小數(shù)點后b位數(shù)為止

      b如果是負數(shù)代表取到十位為止

      elect round(45.926,2) from dual; --45.93
      select round(45.926,1) from dual; -- 45.9
      select round(45.926,0) from dual; --46
      select round(45.926,-1) from dual; --50
      select round(45.926,-2) from dual; --0
      select round(65.926,-2) from dual; --100

      截斷(去尾法)

      select trunc(45.926,2) from dual; --45.92
      select trunc(45.926,1) from dual; -- 45.9
      select trunc(45.926,0) from dual; --45
      select trunc(45.926,-1) from dual; --40
      select trunc(45.926,-2) from dual; --0
      select trunc(65.926,-2) from dual; --0

      求余

      select mod(9,3) from dual; --0
      select mod(9,4) from dual; --1

      2)字符函數(shù)

      substr(str1,起始索引,長度)
      --注意: 起始索引不管寫 0 還是 1 都是從第一個字符開始截取
      select substr('abcdefg',0,3) from dual; --abc
      select substr('abcdefg',1,3) from dual; --abc

      select substr('abcdefg',2,3) from dual; --bcd

      --獲取字符串長度 24 28
      select length('abcdefg') from dual;

      --去除字符左右兩邊的空格
      select trim(' hello ') from dual;

      --替換字符串
      Select replace('hello','l','a') from dual;

      3) 日期函數(shù)

      -查詢今天的日期(查詢的是服務(wù)器上的日期)
      select sysdate from dual;
      --查詢3個月后的今天的日期
      select add_months(sysdate,3) from dual;
      --查詢3天后的日期
      select sysdate + 3 from dual;

      --查詢員工入職的天數(shù)
      select sysdate - hiredate from emp;

      select ceil(sysdate - hiredate) from emp;

      --查詢員工入職的周數(shù)
      select (sysdate - hiredate)/7 from emp;

      --查詢員工入職的月數(shù)
      select months_between(sysdate,hiredate) from emp;

      --查詢員工入職的年份
      select months_between(sysdate,hiredate)/12 from emp;

      4) 轉(zhuǎn)換函數(shù)

      數(shù)值轉(zhuǎn)字符

      select to_char(sal,'$9,999.99') from emp;

      select to_char(sal,'L9,999.99') from emp;
      /*
      to_char(1210.73, '9999.9') 返回 '1210.7'
      to_char(1210.73, '9,999.99') 返回 '1,210.73'
      to_char(1210.73, '$9,999.00') 返回 '$1,210.73'
      to_char(21, '000099') 返回 '000021'
      to_char(852,'xxxx') 返回' 354'

      */

      日期轉(zhuǎn)字符 to_char() (不區(qū)分大小寫)

      select to_char(sysdate,'yyyy-mm-dd hh:mi:ss') from dual;
      select to_char(sysdate,'yyyy-mm-dd hh12:mi:ss') from dual; --默認的是24小時制度
      --只想要年
      select to_char(sysdate,'yyyy') from dual; --2017

      --只想要日
      select to_char(sysdate,'d') from dual; --2 代表一個星期中第幾天(美國周天是一個星期的第一天)
      select to_char(sysdate,'dd') from dual; --10 代表一個月中的第幾天
      select to_char(sysdate,'ddd') from dual; --100 代表一年中的第幾天

      select to_char(sysdate,'day') from dual; --monday(星期的英文)
      select to_char(sysdate,'dy') from dual; --mon 星期的簡寫

      字符轉(zhuǎn)日期

      select to_date('2017-04-10','yyyy-mm-dd') from dual;

      --查詢1981年 -- 1985年入職的員工信息
      select * from emp where hiredate between to_date('1981','yyyy') and to_date('1985','yyyy');

      5) 通用函數(shù)

      nvl(參數(shù)1,參數(shù)2) 如果參數(shù)1 = null 就返回參數(shù)2
      nvl2(參數(shù)1,參數(shù)2,參數(shù)3) 如果參數(shù)1 = null ,就返回參數(shù)3, 否則返回參數(shù)2

         nullif(參數(shù)1,參數(shù)2) 如果參數(shù)1 = 參數(shù)2 那么就返回 null , 否則返回參數(shù)1
         
         coalesce: 返回第一個不為null的值
      

      select nvl2(null,5,6) from dual; --6;

      select nvl2(1,5,6) from dual; --5;

      select nullif(5,6) from dual; --5
      select nullif(6,6) from dual; --null

      select coalesce(null,null,3,5,6) from dual; --3

      2、多行函數(shù)(聚合函數(shù))
      對某一列的所有行進行處理

      max() min count sum avg

      注意:直接忽略空值

      例子:

      --統(tǒng)計員工的平均獎金 550 錯誤 2200/14 =,因為空值產(chǎn)生的影響
      select avg(comm) from emp;
      --統(tǒng)計員工的平均獎金 157.
      select sum(comm)/count(1) from emp;
      select ceil(sum(comm)/count(1)) from emp;

      3、條件表達式
      作用:查詢的時候用來替換列中所有數(shù)據(jù)的值,區(qū)別于取別名,取別名只是單純的給子彈取別名

      /*
      條件表達式:
      case 字段
      when 值1 then 值
      when 值2 then 值
      else
      默認值
      end "別名"
      case、when通用的寫法,mysql和oracle中都可以用

      oracle特有的寫法:decode(字段,if1,then1,if2,then2,else1)
      */
      --給表中姓名取一個中文名
      select
      case ename
      when 'SMITH' then '劉備小二'
      when 'ALLEN' then '薩達'
      else
      '路人甲'
      end "中文名"
      from emp;

      --oracle 特有寫法
      select decode(ename,'SMITH','劉備小二','ALLEN','薩達','路人甲') from emp;

      八、多表查詢
      1、笛卡爾積
      實際上是兩張表的乘積,但是在實際開發(fā)中沒有太大意義,格式: select * from 表1,表2

      select * from emp;
      select * from dept;

      select * from emp, dept;

      select * from emp e1, dept d1 where e1.deptno = d1.deptno;

      2、內(nèi)連接
      隱式內(nèi)聯(lián)接:
      ? 等值內(nèi)聯(lián)接: where e1.deptno = d1.deptno;
      ? 不等值內(nèi)聯(lián)接: where e1.deptno <> d1.deptno;
      ? 自聯(lián)接: 自己連接自己
      顯式內(nèi)聯(lián)接:
      ? select * from 表1 inner join 表2 on 連接條件
      ? inner 關(guān)鍵字可以省略

         --查詢員工編號,員工姓名,經(jīng)理的編號,經(jīng)理的姓名
      

      select e1.empno,e1.ename,e1.mgr,m1.ename
      from emp e1, emp m1 where e1.mgr= m1.empno;

      --查詢員工編號,員工姓名,員工的部門名稱,經(jīng)理的編號,經(jīng)理的姓名
      select e1.empno,e1.ename,d1.dname,e1.mgr,m1.ename
      from emp e1, emp m1,dept d1 where e1.mgr= m1.empno and e1.deptno = d1.deptno;

      --查詢員工編號,員工姓名,員工的部門名稱,經(jīng)理的編號,經(jīng)理的姓名,經(jīng)理的部門名稱
      select e1.empno,e1.ename,d1.dname,e1.mgr,m1.ename,d2.dname
      from emp e1, emp m1,dept d1,dept d2
      where
      e1.mgr= m1.empno
      and e1.deptno = d1.deptno
      and m1.deptno = d2.deptno
      ;

      --查詢員工編號,員工姓名,員工的部門名稱,員工的工資等級,經(jīng)理的編號,經(jīng)理的姓名,經(jīng)理的部門名稱
      select e1.empno,e1.ename,d1.dname,s1.grade,e1.mgr,m1.ename,d2.dname
      from emp e1, emp m1,dept d1,dept d2,salgrade s1
      where
      e1.mgr= m1.empno
      and e1.deptno = d1.deptno
      and m1.deptno = d2.deptno
      and e1.sal between s1.losal and s1.hisal
      ;

      --查詢員工編號,員工姓名,員工的部門名稱,員工的工資等級,經(jīng)理的編號,經(jīng)理的姓名,經(jīng)理的部門名稱,經(jīng)理的工資等級
      select e1.empno,e1.ename,d1.dname,s1.grade,e1.mgr,m1.ename,d2.dname,s2.grade
      from emp e1, emp m1,dept d1,dept d2,salgrade s1,salgrade s2
      where
      e1.mgr= m1.empno
      and e1.deptno = d1.deptno
      and m1.deptno = d2.deptno
      and e1.sal between s1.losal and s1.hisal
      and m1.sal between s2.losal and s2.hisal
      ;

      --查詢員工編號,員工姓名,員工的部門名稱,員工的工資等級,經(jīng)理的編號,經(jīng)理的姓名,經(jīng)理的部門名稱,經(jīng)理的工資等級
      --將工資等級 1,2,3,4 顯示成 中文的 一級 二級 三級...

      select e1.empno,
      e1.ename,
      d1.dname,
      case s1.grade
      when 1 then '一級'--為所有列更換成你想要的信息
      when 2 then '二級'
      when 3 then '三級'
      when 4 then '四級'
      else
      '五級'
      end "等級",--取別名
      e1.mgr,
      m1.ename,
      d2.dname,
      decode(s2.grade,1,'一級',2,'二級',3,'三級',4,'四級','五級') "等級"
      from emp e1, emp m1,dept d1,dept d2,salgrade s1,salgrade s2
      where
      e1.mgr= m1.empno
      and e1.deptno = d1.deptno
      and m1.deptno = d2.deptno
      and e1.sal between s1.losal and s1.hisal
      and m1.sal between s2.losal and s2.hisal
      ;

      --查詢員工姓名和員工部門所處的位置
      select e1.ename,d1.loc from emp e1,dept d1 where e1.deptno = d1.deptno;

      select * from emp e1 inner join dept d1 on e1.deptno = d1.deptno;

      2、外連接
      外連接: (標準,通用寫法)
      ? 左外連接: left outer join 左表中所有的記錄,如果右表沒有對 應(yīng)記錄,就顯示空
      ? 右外連接: right outer join 右表中的所有記錄,如果左表沒有對應(yīng)記錄,就顯示空
      ? outer 關(guān)鍵字可以省略
      Oracle中的外連接: (+) 實際上是如果沒有對應(yīng)的記錄就加上空值
      ? select * from emp e1,dept d1 where e1.deptno = d1.deptno(+);

      select * from emp e1 left outer join dept d1 on e1.deptno = d1.deptno;
      insert into emp(empno,ename) values(9527,'HUAAN');
      select * from emp e1,dept d1 where e1.deptno = d1.deptno(+);

      select * from emp e1 right outer join dept d1 on e1.deptno = d1.deptno;
      select * from emp e1,dept d1 where e1.deptno(+) = d1.deptno;

      九、子查詢
      查詢語句中嵌套查詢語句; 用來解決復(fù)雜的查詢語句

      1、單行子查詢
      = = < <= <> !=

      --查詢最高工資的員工信息
      --1.查詢出最高工資 --5000
      select max(sal) from emp;
      --2. 工資等于最高工資
      select * from emp where sal = (select max(sal) from emp);

      --查詢出比雇員7654的工資高,同時和7788從事相同工作的員工信息
      --1.雇員7654的工資 1250
      select sal from emp where empno = 7654;
      --2.7788從事的工作 ANALYST
      select job from emp where empno = 7788;
      --3.兩個條件合并
      select * from emp where sal > 1250 and job = 'ANALYST';

      select * from emp where sal > (select sal from emp where empno = 7654) and job = (select job from emp where empno = 7788);

      --查詢每個部門最低工資的員工信息和他所在的部門信息
      --1.查詢每個部門的最低工資,分組統(tǒng)計
      select deptno,min(sal) minsal from emp group by deptno;
      --2.員工工資等于他所處部門的最低工資
      select *
      from emp e1,
      (select deptno,min(sal) minsal from emp group by deptno) t1 --將查詢到的結(jié)果作為一張表進行兩表連查
      where e1.deptno = t1.deptno and e1.sal = t1.minsal;
      --3.查詢部門相關(guān)信息
      select *
      from emp e1,
      (select deptno,min(sal) minsal from emp group by deptno) t1,
      dept d1
      where e1.deptno = t1.deptno and e1.sal = t1.minsal and e1.deptno = d1.deptno;

      2、多行子查詢
      in not in >any >all exists not exists

      通常情況下, 數(shù)據(jù)庫中不要出現(xiàn)null 最好的做法加上Not null
      ? null值并不代表不占空間, char(100) null 100個字符

      --查詢不是領(lǐng)導(dǎo)的信息
      select * from emp where empno not in (select mgr from emp);
      select * from emp where empno <>all(select mgr from emp);
      --正確的寫法
      select * from emp where empno not in (select mgr from emp where mgr is not null);

      3、exists(查詢語句)
      存在的意思,判斷一張表里面的記錄是否存在與另外一張表中,作布爾值來處理:, 當查詢語句有結(jié)果的時候, 就是返回true,否則返回的是false,數(shù)據(jù)量比較大的時候是非常高效的

      --查詢有員工的部門的信息
      select * from dept d1 where exists(select * from emp e1 where e1.deptno = d1.deptno );
      1
      2
      十、分頁
      Oracle的分頁查詢需要使用偽列輔助

      偽列 : 在Oracle的結(jié)果集中默認帶有的可以使用的
      ? 不出現(xiàn)在結(jié)果集列中的內(nèi)容.
      ? rownum : 偽列序號, 從1開始
      ? rowid : 偽列地址

      SQL執(zhí)行順序
      ? from … where …group by…h(huán)aving … select…rownum…order by

      默認都是從1開始。

      rownum按照員工id排序后再分頁
      select t.*
      from (
      select rownum rn,e.*
      from (
      select *
      from emp
      order by empno
      ) e
      ) t
      where t.rn between 5 and 9;

      rowid去除表中重復(fù)數(shù)據(jù)
      create table p(
      name varchar2(10)
      );

      insert into p values('黃偉福');
      insert into p values('趙洪');
      insert into p values('楊華');

      delete from p where

      select rowid,p.* from p;
      select distinct * from p;

      delete from p p1 where rowid > (select min(rowid) from p p2 where p1.name = p2.name);

      十一、集合運算
      所有的查詢結(jié)果可能不是來自同一張表, 將查詢結(jié)果進行合并,并去除重復(fù)項

      1、并集
      union : 去除重復(fù)的,并且排序

      union all : 不會去除重復(fù)的

      select * from emp where sal > 1500
      union
      select * from emp where deptno = 20;

      select * from emp where sal > 1500
      union all
      select * from emp where deptno = 20;

      2、交集運算: intersect
      --工資大于1500,并且20號部門下的員工
      select * from emp where sal > 1500;
      select * from emp where deptno = 20;

      select * from emp where sal > 1500
      intersect
      select * from emp where deptno = 20;

      3、差集運算
      兩個結(jié)果相減

      --1981年入職員工(不包括總裁和經(jīng)理)
      --1981年入職員工
      select * from emp where to_char(hiredate,'yyyy')='1981';

      --總裁和經(jīng)理
      select * from emp where job = 'PRESIDENT' or job = 'MANAGER';

      select * from emp where to_char(hiredate,'yyyy')='1981'
      minus
      select * from emp where job = 'PRESIDENT' or job = 'MANAGER';

      4、集合運算中的注意事項
      1.列的類型要一致
      2.按照順序?qū)?br> 3.列的數(shù)量要一致,如果不足,用空值填充

      select ename,sal from emp where sal > 1500
      union
      select ename,sal from emp where deptno = 20;
      --列的類型不匹配
      select ename,sal from emp where sal > 1500
      union
      select sal,ename from emp where deptno = 20;

      --列的數(shù)量不匹配
      select ename,sal,deptno from emp where sal > 1500
      union
      select ename,sal from emp where deptno = 20;

      select ename,sal,deptno from emp where sal > 1500
      union
      select ename,sal,null from emp where deptno = 20;

      select ename,sal,deptno from emp where sal > 1500
      union
      select ename,sal,66 from emp where deptno = 20;

      select * from emp;
      select * from dept;

      十二、DDL語句管理表
      1、表空間
      邏輯單位, 通常我們新建一個項目,就會去新建表空間,在表空間中創(chuàng)建用戶來創(chuàng)建表

      創(chuàng)建表空間

      語法:
      ? create tablespace 表空間的名稱
      ? datafile ‘文件的路徑(服務(wù)器上)’
      ? size 大小
      ? autoextend on 自動擴展
      ? next 每次擴展的大小

      --創(chuàng)建表空間-
      create tablespace canghe
      datafile 'C:\oracle\canghe.dbf'
      size 100m
      autoextend on
      next 10m;

      刪除表空間

      --刪除表空間
      drop tablespace canghe;

      2、創(chuàng)建用戶
      create user 用戶名
      identified by 密碼
      default tablespace 表空間的名稱

      create user canghe
      identified by canghe
      default tablespace canghe;

      授權(quán)
      --授予 dba的角色
      grant dba to canghe;
      select * from scott.emp;

      3、創(chuàng)建表
      create table 表名(
      ? 列名 列的類型 [列的約束],
      ? 列名 列的類型 [列的約束]
      ? );

      列的類型:
      varchar ,在Oracle中,目前是支持的, 但是不保證以后還支持
      varchar2(長度) 可變字符長度 varchar2(10) hello 占5個字符
      char(長度) 固定長度字符 char(10) hello 占10個字符,用空格填充
      number(總長度,小數(shù)長度) 數(shù)字類型 --小數(shù)長度不能大于等于總長度

       date                   年月日時分秒 2017/4/13 9:43:49
       timestamp              時間戳, 比date類型更加精確 13-APR-17 09.44.08.272000 AM +08:00
       
       LONG/CLOB : 存放一本小說
       BLOB      : 存放電影  java 存進去,  再讀取出來
      

      使用子查詢的方式創(chuàng)建表

       create table 表名 as 查詢語句; 
       
         注意: 只會復(fù)制表結(jié)構(gòu)和表中的數(shù)據(jù),不會復(fù)制列的約束     
               如果查詢語句有結(jié)果, 就是復(fù)制 表結(jié)構(gòu)和數(shù)據(jù)
               如果查詢語句沒有結(jié)果, 就是復(fù)制 表結(jié)構(gòu)
      

      create table test1(
      name1 varchar2(10),
      name2 char(10),
      age number(4,2)
      );
      create table 表名 as 查詢語句; 復(fù)制表
      create table emp as select * from scott.emp;

      4、修改表
      添加咧

      alter table 表名 add 列

      修改列

      修改列類型:modify

      修改列名:rename

      刪除咧

      alter table 表名 drop column 列名;

      修改列名

      alter table 表名 rename column 列名;

      重命名表

      rename 舊表名 to 新表名;

      5、刪除表
      drop table 表名

      6、表的五大約束
      主鍵約束

      primary key

      非空約束

      not null

      唯一約束

      unique

      外鍵約束

      添加外鍵約束:

      alter table 表名 add foreign key(添加約束的字段) references 引用的表名 (引用的字段)

      插入:先主表、再從表

      刪除:先從表,再主表

      強制刪除表(不建議):

      drop table 表名 cascade constraint;

      級聯(lián)刪除:

      添加外鍵約束,使用級聯(lián)約束 ,在刪除的時候,使用級聯(lián)刪除

      ----添加外鍵約束,使用級聯(lián)約束 ,在刪除的時候,使用級聯(lián)刪除
      alter table product add foreign key(cno) references category(cid) on delete cascade;

      insert into category values(2,'電腦辦公');
      insert into product values(11,'外星人',2);

      --級聯(lián)刪除 : 首先去從表中找有沒有 關(guān)聯(lián)數(shù)據(jù), 如果在從表中找到關(guān)聯(lián)數(shù)據(jù),先刪除從表中關(guān)聯(lián)數(shù)據(jù),然后再刪除表中的數(shù)據(jù)
      delete from category where cid = 2;

      檢查約束

      check( 列名 in (‘值1’,‘值2’,‘值3’))

      十三、DML管理表數(shù)據(jù)
      1、插入數(shù)據(jù)
      指定列名插入

      insert into 表名 values(所有列的值都要對應(yīng)寫上)

      不指定列名插入

      insert into 表名(列1,列2) values(值1,值2);

      使用子查詢插入

      insert into 表名 查詢語句

      2、修改數(shù)據(jù)
      update 表名 set 列名 = 列的值 [where 條件]

      3、刪除數(shù)據(jù)
      delete from 表名 [where 條件]

      delete和truncate 區(qū)別

         delete:                 truncate:
          DML                    DDL
          逐條刪除               先刪除表再創(chuàng)建表
          支持事務(wù)操作           不支持事務(wù)操作,
                                 執(zhí)行效率要高  
      

      十四、其他數(shù)據(jù)庫對象
      1、事務(wù)
      事務(wù): 就是一系列的操作,要么都成功,要么都失敗
      ? 四大特性: 原子性,隔離性,持久性,一致性
      ?

      如果不考慮隔離級別: 臟讀,虛讀,不可重復(fù)讀
      MYSQL隔離級別: READ UNCOMMITTED , READ COMMITTED, REPEATABLE READ, SERIALIAZABLE
      ORACLE隔離級別: READ COMMITTED SERIALIZABLE READ ONLY
      默認隔離級別: READ COMMITTED

      提交 : commit
      事務(wù)的保存點/回滾點: savepoint 保存點的名稱
      回滾: rollback

      2、視圖
      視圖: 是對查詢結(jié)果的一個封裝
      ? 視圖里面所有的數(shù)據(jù),都是來自于它查詢的那張表,視圖本身不存儲任何數(shù)據(jù)
      ? 1.能夠封裝復(fù)雜的查詢結(jié)果
      ? 2.屏蔽表中的細節(jié)
      ? 語法:
      ? create [or replace] view 視圖的名稱 as 查詢語句 [ with read only]
      ? 注意: 通常不要通過視圖去修改,視圖創(chuàng)建的時候,通常要加上with read only

      --創(chuàng)建一個視圖
      create or replace view view_test1 as select ename,job,mgr from emp;

      --通過視圖修改數(shù)據(jù)
      update view_test1 set ename='SMITH2' where ename = 'SMITH';

      --創(chuàng)建一個只讀視圖
      create or replace view view_test2 as select ename,job,mgr from emp with read only;

      update view_test2 set ename='SMITH3' where ename = 'SMITH2';

      -同義詞的概念(就是為視圖取的一個別名)
      create synonym dept for view_test3;

      3、序列
      oracle中用來控制自增長的

      語法:
      create sequence 序列的名稱
      start with 從幾開始
      increment by 每次增長多少
      maxvalue 最大值 | nomaxvalue
      minvalue 最小值 | nominvalue
      cycle | nocycle 是否循環(huán) 1,2,3,1,2,3
      cache 緩存的數(shù)量3 | nocache 1,2,3,4,5,6

        如何從序列獲取值
            currval : 當前值
            nextval : 下一個值
            
                 注意: currval 需要在調(diào)用nextval之后才能使用      
                 
                 永不回頭,往下取數(shù)據(jù), 無論發(fā)生異常, 回滾   
      

      --序列用的最多的一種寫法
      create sequence seq_test2;
      select seq_test2.nextval from dual;

      4、索引
      索引:相當于是一本書的目錄,能夠提高我們的查詢效率
      如果某一列,你經(jīng)常用來作為查詢條件,那么就有必要創(chuàng)建索引,數(shù)據(jù)量比較的情況

         語法: 
               create index 索引的名稱 on 表名(列)   
          
         注意:主鍵約束自帶主鍵索引, 唯一約束自帶唯一索引
         
         索引原理: btree   balance Tree 平衡二叉樹
         
               如果某列作為查詢條件的時候,可以提高查詢效率,但是修改的時候,會變慢
               
               索引創(chuàng)建好之后,過了一段,DBA都會去做重構(gòu)索引
               
         SQL調(diào)優(yōu):
               1.查看執(zhí)行計劃F5
               2. 分析里面的cost 和 影響行數(shù), 想辦法降低  
      

      十五、PLSQL編程
      1、概述
      procedure Language 過程語言 Oracle對SQL的一個擴展
      ? 讓我們能夠像在java中一樣寫 if else else if 條件, 還可以編寫循環(huán)邏輯 for while

      2、基本語法
      declare
      --聲明變量
      變量名 變量類型;
      變量名 變量類型 := 初始值;
      vsal emp.sal%type; --引用型的變量
      vrow emp%rowtype; --聲明記錄型變量
      begin
      --業(yè)務(wù)邏輯,比如輸出一句話:
      dbms_output.put_line()相當于java中 syso
      end;

      declare
      i varchar2(10) := '張三';
      begin
      dbms_output.put_line(i);
      end;

      3、變量
      %type --引用型變量

      %rowtype --記錄型變量

      4、PL條件判斷
      if then

       elsif then
         
       else 
       
       end if;
      

      declare
      age number := &aaa;
      begin
      if age < 18 then
      dbms_output.put_line('小屁孩');
      elsif age>=18 and age <=24 then
      dbms_output.put_line('年輕人');
      elsif age>24 and age < 40 then
      dbms_output.put_line('老司機');
      else
      dbms_output.put_line('老年人');
      end if;
      end;

      5、循環(huán)操作
      while 循環(huán)
      while 條件 loop

        end loop;
      

      for循環(huán)
      for 變量 in [reverse] 起始值..結(jié)束值 loop

        end loop;
      

      loop循環(huán)
      loop
      exit when 條件
      end loop;

      --輸出1~10
      declare
      i number :=1;
      begin
      while i<=10 loop
      dbms_output.put_line(i);
      i := i+1;
      end loop;
      end;

      --輸出1~10
      declare

      begin
      for i in reverse 1..10 loop
      dbms_output.put_line(i);
      end loop;
      end;

      --輸出1~10
      declare
      i number :=1;
      begin
      loop
      exit when i>10;
      dbms_output.put_line(i);
      i := i+1;
      end loop;
      end;

      /*




      輸出 m
      x : [-m,m]
      y : [-m,m]

      輸出所有滿足條件的 : abs(y)+abs(x) <=m

      m取值
      /
      --使用PLSQL輸出菱形
      declare
      m number := 10;
      begin
      for x in -m..m loop
      for y in -m..m loop
      if abs(y) + abs(x) <= m then
      dbms_output.put('
      ');
      else
      dbms_output.put(' ');
      end if;
      end loop;
      dbms_output.new_line();
      end loop;
      end;

      --使用PLSQL輸出三角形,只要是三個角
      declare
      m number := 10;
      begin
      for x in reverse -m..m loop
      for y in -m..m loop
      if abs(y) + abs(x) <= m and x>=0 then
      dbms_output.put('*');
      else
      dbms_output.put(' ');
      end if;
      end loop;
      dbms_output.new_line();
      end loop;
      end;

      十六、游標
      用來操作查詢的結(jié)果集.相當于JDBC中的ResultSe

      語法: cursor 游標名[(參數(shù)名 參數(shù)類型)] is 查詢結(jié)果集

         開發(fā)步驟:
             1. 聲明游標
             2. 打開游標       open 游標名
             3. 從游標中取數(shù)據(jù)  fetch 游標名 into 變量
                           游標名%found :找到數(shù)據(jù)
                           游標名%notfound : 沒有找到數(shù)據(jù) 
             4. 關(guān)閉游標       close 游標名
             
        系統(tǒng)引用游標
             1. 聲明游標 : 游標名 sys_refcursor
             2. 打開游標: open 游標名 for 結(jié)果集
             3. 從游標中取數(shù)據(jù)
             4. 關(guān)閉游標
                  
       for循環(huán)遍歷游標:
             不需要聲明額外變量
             不需要打開游標
             不需要關(guān)閉游標      
      

      1、不帶參數(shù)游標
      /
      --輸出員工表中所有的員工姓名和工資(不帶參數(shù)游標)
      /

      游標:所有員工
      聲明一個變量,用來記錄一行數(shù)據(jù) %rowtype
      */
      declare
      --游標
      cursor vrows is select * from emp;
      --s聲明變量,記錄一行數(shù)據(jù)
      vrow emp%rowtype;
      begin
      --1.打開游標
      open vrows;
      --2.從游標提取數(shù)據(jù)
      --循環(huán)取數(shù)據(jù)
      loop
      fetch vrows into vrow;
      exit when vrows%notfound;
      dbms_output.put_line('姓名:'||vrow.ename ||' 工資: ' || vrow.sal);
      end loop;
      --3.關(guān)閉游標
      close vrows;
      end;

      2、帶參數(shù)的游標
      --輸出指定部門下的員工姓名和工資
      /*
      游標: 指定部門的所有員工
      聲明一個變量記錄一行數(shù)據(jù)
      */
      declare
      --聲明游標
      cursor vrows(dno number) is select * from emp where deptno = dno;
      --聲明變量
      vrow emp%rowtype;
      begin
      --1.打開游標 , 指定10號部門
      open vrows(10);
      --2. 循環(huán)遍歷,取數(shù)據(jù)
      loop
      fetch vrows into vrow;
      exit when vrows%notfound;
      dbms_output.put_line('姓名:'||vrow.ename ||' 工資: ' || vrow.sal);
      end loop;
      close vrows;
      end;

      3、系統(tǒng)引用游標
      --輸出員工表中所有的員工姓名和工資
      declare
      --聲明系統(tǒng)引用游標
      vrows sys_refcursor;
      --聲明一個變量
      vrow emp%rowtype;
      begin
      --1.打開游標
      open vrows for select * from emp;
      --2.取數(shù)據(jù)
      loop
      fetch vrows into vrow;
      exit when vrows%notfound;
      dbms_output.put_line('姓名:'||vrow.ename ||' 工資: ' || vrow.sal);
      end loop;
      close vrows;
      end;

      4、-使用for循環(huán)遍歷游標
      --按照員工工作給所有員工漲工資,總裁漲1000,經(jīng)理漲800,其他人漲400
      /*
      游標 : 所有員工
      聲明一個記錄一行數(shù)據(jù)
      */
      declare
      --聲明游標
      cursor vrows is select * from emp;
      --聲明一個變量
      vrow emp%rowtype;
      begin
      --1.打開游標
      open vrows;
      --2.循環(huán)取數(shù)據(jù)
      loop
      --取數(shù)據(jù)
      fetch vrows into vrow;
      --退出條件
      exit when vrows%notfound;
      --根據(jù)不同的職位,漲工資 總裁漲1000,經(jīng)理漲800,其他人漲400
      if vrow.job = 'PRESIDENT' then
      update emp set sal = sal + 1000 where empno = vrow.empno;
      elsif vrow.job = 'MANAGER' then
      update emp set sal = sal + 800 where empno = vrow.empno;
      else
      update emp set sal = sal + 400 where empno = vrow.empno;
      end if;
      end loop;
      --3.關(guān)閉游標
      close vrows;
      --4.提交事務(wù)
      commit;
      end;

      十七、例外
      例外:(意外)程序運行的過程發(fā)生異常,相當于是JAVA中的異常

      declare
      --聲明變量
      begin
      --業(yè)務(wù)邏輯
      exception
      --處理異常
      when 異常1 then
      ...
      when 異常2 then
      ...
      when others then
      ...處理其它異常
      end;

      zero_divide : 除零異常
      value_error : 類型轉(zhuǎn)換異常
      too_many_rows : 查詢出多行記錄,但是賦值給了rowtype記錄一行數(shù)據(jù)變量
      no_data_found : 沒有找到數(shù)據(jù)

      自定義異常:
      異常名 exception;
      raise 異常名

      --查詢指定編號的員工,如果沒有找到,則拋出自定義的異常
      /*
      --錯誤的演示

       1.聲明一個變量 %rowtype
       2.查詢員工信息,保存起來
       3.判斷員工信息是否為空
       4. 如果是 則拋出異常
      

      */
      declare
      -- 1.聲明一個變量 %rowtype
      vrow emp%rowtype;
      --2 .聲明一個自定義的異常
      no_emp exception;
      begin
      --查詢員工信息,保存起來
      select * into vrow from emp where empno = 8888; --拋出異常

      if vrow.sal is null then
      raise no_emp; --拋出自定義的異常
      end if;
      exception
      when no_emp then
      dbms_output.put_line('輸出了自定義的異常');
      when others then
      dbms_output.put_line('輸出了其它異常'||sqlerrm);
      end;

      --查詢指定編號的員工,如果沒有找到,則拋出自定義的異常
      /*
      游標來判斷
      %found %notfound
      聲明一個游標
      聲明一個變量,記錄數(shù)據(jù)
      從游標中取記錄
      如果有,則不管它
      如果沒有就拋出自定義的異常
      */
      declare
      --聲明游標
      cursor vrows is select * from emp where empno=8888;
      --聲明一個記錄型變量
      vrow emp%rowtype;
      --聲明一個自定義異常
      no_emp exception;
      begin
      --1.打開游標
      open vrows;
      --2.取數(shù)據(jù)
      fetch vrows into vrow;
      --3.判斷游標是否有數(shù)據(jù)
      if vrows%notfound then
      raise no_emp;
      end if;
      close vrows;
      exception
      when no_emp then
      dbms_output.put_line('發(fā)生了自定義的異常');
      end;

      十八、存儲過程
      存儲過程: 實際上是封裝在服務(wù)器上一段PLSQL代碼片斷,已經(jīng)編譯好了的代碼
      1.客戶端取調(diào)用存儲過程,執(zhí)行效率就會非常高效
      語法:
      create [or replace] procedure 存儲過程的名稱(參數(shù)名 in|out 參數(shù)類型,參數(shù)名 in|out 參數(shù)類型)
      is | as
      --聲明部分
      begin
      --業(yè)務(wù)邏輯
      end;

      /
      --給指定員工漲薪,并打印漲薪前和漲薪后的工資
      /

      參數(shù) : in 員工編號
      參數(shù) : in 漲多少

      聲明一個變量 : 存儲漲工資前的工資
      
      查詢出當前是多少
      打印漲薪前的工資
      更新工資
      打印漲薪后的工資          
      

      */
      create or replace procedure proc_updatesal(vempno in number,vnum in number)
      is
      --聲明變量.記錄當前工資
      vsal number;
      begin
      --查詢當前的工資
      select sal into vsal from emp where empno = vempno;
      --輸出漲薪前的工資
      dbms_output.put_line('漲薪前:'||vsal);
      --更新工資
      update emp set sal = vsal + vnum where empno = vempno;
      --輸出漲薪后的工資
      dbms_output.put_line('漲薪后:'||(vsal+vnum));
      --提交
      commit;
      end;

      --調(diào)用方式1
      call proc_updatesal(7788,10);

      --調(diào)用方式2 用的最多的方式
      declare

      begin
      proc_updatesal(7788,-100);
      end;

      十九、存儲函數(shù)
      1、基本語法和例子
      存儲函數(shù): 實際上是一段封裝是Oracle服務(wù)器中的一段PLSQL代碼片斷,它是已經(jīng)編譯好了的代碼片段
      ?

      語法: 
           create [or replace] function 存儲函數(shù)的名稱(參數(shù)名 in|out 參數(shù)類型,參數(shù)名 in|out 參數(shù)類型) return 參數(shù)類型
           is | as
           
           begin
             
           end;
      存儲過程和函數(shù)的區(qū)別:
           1.它們本質(zhì)上沒有區(qū)別
           2.函數(shù)存在的意義是給過程調(diào)用   存儲過程里面調(diào)用存儲函數(shù)
           3.函數(shù)可以在sql語句里面直接調(diào)用
           4.存儲過程能實現(xiàn)的,存儲函數(shù)也能實現(xiàn),存儲函數(shù)能實現(xiàn)的,過程也能實現(xiàn)
           
      默認是 in     
      

      /
      --查詢指定員工的年薪
      /

      參數(shù) : 員工的編號
      返回 : 年薪
      /
      create or replace function func_getsal(vempno number) return number
      is
      --聲明變量.保存年薪
      vtotalsal number;
      begin
      select sal
      12 + nvl(comm,0) into vtotalsal from emp where empno = vempno;
      return vtotalsal;
      end;

      --調(diào)用存儲函數(shù)
      declare
      vsal number;
      begin
      vsal := func_getsal(7788);
      dbms_output.put_line(vsal);
      end;

      2、java調(diào)用存儲過程、存儲函數(shù)
      1)基本套路

      /*
      JAVA調(diào)用存儲過程
      JDBC的開發(fā)步驟:
      1.導(dǎo)入驅(qū)動包
      2.注冊驅(qū)動
      3.獲取連接
      4.獲取執(zhí)行SQL的statement
      5.封裝參數(shù)
      6.執(zhí)行SQL
      7.獲取結(jié)果
      8.釋放資源
      */

      /*
      封裝一個存儲過程 : 輸出所有表中的記錄

      輸出類型 : 游標
      */
      create or replace procedure proc_getemps(vrows out sys_refcursor)
      is

      begin
      --1.打開游標, 給游標賦值
      open vrows for select * from emp;
      end;

      2)調(diào)用存儲過程

      /**
      * 查詢指定員工的年薪,用存儲過程實現(xiàn)
      * create or replace procedure proc_gettotalsal(vempno in number,vtotalsal out number)
      is

      	begin
      	  select sal*12 + nvl(comm,0) into vtotalsal from emp where empno = vempno;
      	end;
       * @throws Exception
       */
      public void test1() throws Exception {
      	//注冊驅(qū)動
      	Class.forName("oracle.jdbc.driver.OracleDriver");
      	//獲取連接
      	String url="jdbc:oracle:thin:@106.13.43.205:1521:orcl";
      	String user="canghe";
      	String password="canghe";
      	Connection conn = DriverManager.getConnection(url, user, password);
      	//獲取執(zhí)行對象
      	String sql="{call proc_gettotalsal(?,?)}";
      	CallableStatement state = conn.prepareCall(sql);
      	//為問號賦值
      	state.setInt(1, 7654);//設(shè)置員工編號
      	state.registerOutParameter(2, OracleTypes.NUMBER);
      	//執(zhí)行statement
      	state.execute();
      	//獲取結(jié)果
      	int totle = state.getInt(2);
      	//輸出結(jié)果
      	System.out.println(totle);
      	//釋放資源
      	state.close();
      	conn.close();
      }
      

      3)調(diào)用存儲函數(shù)

      //調(diào)用存儲函數(shù)
      /*
      create or replace function func_getsal(vempno number) return number
      is
      --聲明變量.保存年薪
      vtotalsal number;
      begin
      select sal*12 + nvl(comm,0) into vtotalsal from emp where empno = vempno;
      return vtotalsal;
      end;
      */
      public void test2() throws Exception{
      //注冊驅(qū)動
      Class.forName("oracle.jdbc.driver.OracleDriver");
      //2.獲取連接
      String url = "jdbc:oracle:thin:@106.13.43.205:1521:orcl";
      String username = "canghe";
      String password = "canghe";
      Connection conn = DriverManager.getConnection(url, username,password);
      //3.獲取執(zhí)行SQL的statement
      String sql = " {?= call func_getsal(?)}";
      CallableStatement state = conn.prepareCall(sql);
      //4.封裝參數(shù)
      //注冊返回類型參數(shù)
      state.registerOutParameter(1, OracleTypes.NUMBER);
      //設(shè)置第二個參數(shù)
      state.setInt(2, 7788);
      //5.執(zhí)行SQL
      state.execute();
      //6.獲取結(jié)果
      int totalsal = state.getInt(1);
      System.out.println("年薪 : ====" +totalsal);
      //7.釋放資源
      state.close();
      conn.close();
      }

      3)通過游標輸出結(jié)果集

      /**
      * 通過游標輸出結(jié)果集
      * @throws Exception
      */
      public void test3() throws Exception{
      //注冊驅(qū)動
      Class.forName("oracle.jdbc.driver.OracleDriver");
      //2.獲取連接
      String url = "jdbc:oracle:thin:@106.13.43.205:1521:orcl";
      String username = "canghe";
      String password = "canghe";
      Connection conn = DriverManager.getConnection(url, username,password);
      //3.獲取執(zhí)行SQL的statement
      String sql = "{call proc_getemps(?)}";
      CallableStatement call = conn.prepareCall(sql);
      //接口 --- > 對象 -->實現(xiàn)類的名稱
      System.out.println(call.getClass().getName());
      OracleCallableStatement oracleCall = (OracleCallableStatement)call;
      //4.注冊輸出類型的參數(shù)
      call.registerOutParameter(1, OracleTypes.CURSOR);
      //5.執(zhí)行SQL
      call.execute();
      //6.獲取執(zhí)行的結(jié)果
      ResultSet resultSet = oracleCall.getCursor(1);
      while(resultSet.next()){
      int empno = resultSet.getInt("empno");
      String name = resultSet.getString("ename");
      System.out.println(empno +" ==== "+name);
      }

      	//7.釋放資源
      	resultSet.close();
      	call.close();
      	conn.close();
      }
      

      二十、觸發(fā)器
      觸發(fā)器: 當用戶執(zhí)行了 insert | update | delete 這些操作之后, 可以觸發(fā)一系列其它的動作/業(yè)務(wù)邏輯
      作用 :
      在動作執(zhí)行之前或者之后,觸發(fā)業(yè)務(wù)處理邏輯
      插入數(shù)據(jù),做一些校驗

         語法:
             create [or replace] trigger 觸發(fā)器的名稱
             before | after
             insert | update | delete 
             on 表名
             [for each row]
             declare
             
             begin
               
             end;
             
         觸發(fā)器的分類:
             語句級觸發(fā)器:   不管影響多少行, 都只會執(zhí)行一次
             
             行級觸發(fā)器:     影響多少行,就觸發(fā)多少次
                    :old  代表舊的記錄, 更新前的記錄
                    :new  代表的是新的記錄
      

      --新員工入職之后,輸出一句話: 歡迎加入黑馬程序員
      create or replace trigger tri_test1
      after
      insert
      on emp
      declare

      begin
      dbms_output.put_line('歡迎加入黑馬程序員');
      end;

      insert into emp(empno,ename) values(9527,'HUAAN');

      --數(shù)據(jù)校驗, 星期六老板不在, 不能辦理新員工入職
      --在插入數(shù)據(jù)之前
      --判斷當前日期是否是周六
      --如果是周六,就不能插入
      create or replace trigger tri_test2
      before
      insert
      on emp
      declare
      --聲明變量
      vday varchar2(10);
      begin
      --查詢當前
      select trim(to_char(sysdate,'day')) into vday from dual;
      --判斷當前日期:
      if vday = 'saturday' then
      dbms_output.put_line('老板不在,不能辦理入職');
      --拋出系統(tǒng)異常
      raise_application_error(-20001,'老板不在,不能辦理入職');
      end if;
      end;

      insert into emp(empno,ename) values(9528,'HUAAN2');

      --更新所有的工資 輸出一句話
      create or replace trigger tri_test3
      after
      update
      on emp
      for each row
      declare

      begin
      dbms_output.put_line('更新了數(shù)據(jù)');
      end;

      update emp set sal = sal+10;

      --判斷員工漲工資后的工資一定要大于漲工資前的工資
      /*
      200 --> 100
      觸發(fā)器 : before
      舊的工資
      新的工資
      如果舊的工資大于新的工資 , 拋出異常,不讓它執(zhí)行成功

      觸發(fā)器中不能提交事務(wù),也不能回滾事務(wù)
      */
      create or replace trigger tri_updatesal
      before
      update
      on emp
      for each row
      declare

      begin
      if :old.sal > :new.sal then
      raise_application_error(-20002,'舊的工資不能大于新的工資');
      end if;
      end;

      update emp set sal = sal + 10;
      select * from emp;

      update emp set sal = sal - 100;

      /*
      模擬mysql中ID的自增屬性 auto_increment
      insert into person(null,'張三');

      觸發(fā)器:

      pid=1 insert pid=1

      序列 : create sequence seq_person_pid;
      */
      create table person(
      pid number primary key,
      pname varchar2(20)
      );

      insert into person values(null,'張三');

      create sequence seq_person_pid;

      --觸發(fā)器
      create or replace trigger tri_add_person_pid
      before
      insert
      on person
      for each row
      declare

      begin
      dbms_output.put_line(:new.pname);
      --給新記錄 pid 賦值
      select seq_person_pid.nextval into :new.pid from dual;
      end;

      insert into person values(null,'張三');

      select * from person;
      ————————————————
      原文鏈接:https://blog.csdn.net/qq_43270074/article/details/85727108

      posted @ 2019-10-19 14:40  Kannic  閱讀(406)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 人妻丝袜无码专区视频网站| 开心激情站开心激情网六月婷婷| 欧美巨大极度另类| 日本边添边摸边做边爱| 日本高清视频网站www| 久热这里有精品视频在线| 亚洲国产成人无码影院| 金乡县| 亚洲国产精品成人av网| 91高清免费国产自产拍| 亚洲热妇无码av在线播放| 无码av中文字幕久久专区| 久久三级中文欧大战字幕| 丁香婷婷综合激情五月色| 久久夜色精品国产噜噜亚洲sv| 国产中文字幕一区二区| 99久久久无码国产精品免费 | 依依成人精品视频在线观看 | 亚洲欧美综合人成在线| 国产对白叫床清晰在线播放| 少妇伦子伦情品无吗| 亚洲精品一区二区三天美| 亚洲香蕉伊综合在人在线| 久久天天躁狠狠躁夜夜avapp| 亚洲精品一区二区在线播| 久久国产精品老人性| 久久96热在精品国产高清| 国产精品伦人一久二久三久| 无码日韩精品91超碰| 国产一区二区不卡91| 一区二区不卡99精品日韩| 国产95在线 | 亚洲| 69天堂人成无码免费视频| 亚洲制服无码一区二区三区 | 色94色欧美sute亚洲线路二| 国产精品老熟女露脸视频| 欧美肥老太交视频免费| 野花香视频在线观看免费高清版| 九九热免费精品在线视频| 西西人体44WWW高清大胆| 国产午夜福利视频合集|