Oracle資料庫小知識點整理

来源:https://www.cnblogs.com/yangzhengier/archive/2019/11/13/11846838.html
-Advertisement-
Play Games

-- 資料庫存儲數據 -- 市面上主流的資料庫有哪些 -- 甲骨文 oracle mysql -- IBM db2 金融 -- 微軟 sqlserver --這些是關係型資料庫。 --NOSQL 不僅僅是sql,典型 mongodb. --資料庫的語言有哪些分類 -- *************** ...


-- 資料庫存儲數據

 

-- 市面上主流的資料庫有哪些

 

-- 甲骨文  oracle   mysql

--  IBM  db2  金融

--  微軟  sqlserver

 

--這些是關係型資料庫。

 

--NOSQL  不僅僅是sql,典型 mongodb.

 

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

--資料庫的語言有哪些分類

-- **************************************

/***

1.數據定義語言(DDL),create,alter,drop

2.數據操縱語言(DML),select,update,insert,delete

3.數據事務語言, commit,savepoint,rollback

事務特性:原子性,一致性,持久性,隔離型,

 

...........後面補充.............

 

在關係型資料庫中數據是以table

(二維數據結構,行和列的形式)

來組織數據

 

table 就是表來組織數據,這個table的設計的規範是什麼?

 

--三範式  *****************

 

--第一範式:資料庫表中的欄位應該最小單位,

是不能夠分割(本地化)

--第二範式:資料庫表中的一個欄位

不能由另外一個欄位通過計算得出。

 

age 

birthday

 

工資

養老保險費用

 

***/

 

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

-- 創建表  oracle  列名和列的類型來定義的

--1.數據類型:

--number 數值類型  number(長度),number(10)

--number(長度,小數點位數)   number(7,2)

--2.char類型   char(長度),定長  char(6) 固定長度為6位

--3.varchar2類型  varchar2(20)

--4.date類型  日期類型

--5.int類型,表示一個正整數

-- 大文本類型 blob ,clob

-- 路徑

 

-- 首先我們來創建一張表   命名規範 t_

create   table   t_students

(

      sn  number(7)   primary  key ,--學號 -- 主鍵(唯一不能重覆),主鍵約束

      sname  varchar2(20) , --學生姓名

      spwd   char(6), -- 學生密碼

      sbirthday  date,--出生年月

      smoney      number(7,2),     --賬戶金額

      job      varchar2(20), --學生職位

      saddress  varchar2(20),--學生籍貫

      sphone  char(11)   --學生手機號碼

 

)

 

--查詢表

select   *   from  t_students

 

 

-- 插入數據

insert  into   t_students  values(1, '趙蓉','12345',

to_date('1992-12-03','yyyy-MM-dd'),500.65,'學生會委員',

'鹽城','13913321089');

commit;

 

 

insert  into   t_students  values(2, '秦日霞','123456',

to_date('1992-11-03','yyyy-MM-dd'),1500.65,'學生會委員',

'鹽城','13913321085');

commit;

 

 

-- 修改表

 

-- 表增加一個欄位

alter table  t_students  add  ssex  char(4);

 

--表欄位類型修改

alter  table t_students  modify  saddress  varchar2(15)

 

--刪除表的欄位

alter  table t_students   drop  column ssex ;

 

-- 刪除整個表

drop  table t_students;

 

select  length(s.spwd) 

 from  t_students  s   where  s.sname='趙蓉'

 

 

 

-- 創建表

 

create  table  t_employees

(

    eid   number(6) primary key, -- 員工編號  主鍵

    ename  varchar2(20),  --員工姓名

    epwd  char(5) , -- 員工密碼

    ebirthday  date, --出生年月

    esalary   number(7,2), --工資

    ejob  varchar2(20), --職位

    esex  char(4) --性別

 

)

 

-- oracle序列機制,自增長機制    sequence

create  sequence  seq_employees

start  with 100 --開始編號

increment  by  2  --步長

nocache  --沒有緩存,立即生成

 

--查看表結構

desc  t_employees

 

select  *  from  t_employees  for  update

 

 

select  *  from  t_employees  where

 

 

 

--數據操作語言(select ,insert,update,delete)DML

--select 操作 ,不需要commit  70%

--insert,update,delete  都需要commit  30%

 

--查詢

select   *   from  t_employees

 

--插入

-- 插入數據

insert  into  t_employees  values(seq_employees.nextval,

'胡瓜','1234',to_date('1992-12-30','yyyy-MM-dd'),10000.88,

'職工','男');

 

insert  into  t_employees  values(seq_employees.nextval,

'李欣','11111',to_date('1992/08/30','yyyy/MM/dd'),12000.88,'組長','男');

commit;

 

--更新數據

update  t_employees e set e.epwd='12345' ;

commit;

 

update t_employees  e  set  e.epwd='00000'  where e.ename='李欣';

commit;

 

--刪除數據

delete  from   t_employees

 

delete  from  t_employees  e  where e.eid=100;

commit;

 

 

 

 

--約束

 

--1.主鍵約束,唯一不能重覆,數據唯一性  primary key

--2.非空約束 這個欄位的取值不能為空   not null

--3.預設約束  這個欄位取值如果不給值,取預設值  default

--4.檢查約束  這個欄位取值是一定範圍內  check(欄位取值範圍)

--5.外鍵約束  一個欄位取值從屬於另外一個的值

 

drop  table  t_stus

 

create  table  t_stus

(

    sid  number(3)  primary key,

    sname  varchar2(20)   not null

   

 

)

 

insert  into  t_stus   values(seq_stus.nextval,null);

commit;

 

insert  into  t_stus   values(seq_stus.nextval,'李欣',to_date('1976-12-30','yyyy-MM-dd'));

commit;

 

insert  into  t_stus   values(seq_stus.nextval,'李欣1',default);

commit;

 

insert  into  t_stus   values(seq_stus.nextval,'李欣1',default,'男');

commit;

 

 

select   *  from   t_stus

 

--default  是預設,sysdate是oracle預設時間的關鍵字

alter  table  t_stus  add  birthday  date  default sysdate;

 

alter  table  t_stus  add   sex  char(4)

 check(sex  in('男','女'));

 

 

 -- 創建一張表,樹狀菜單,自身關聯表 一對多

 create  table  t_menu

 (

     fid   number(4)  primary  key, --父id

     fmenuname  varchar2(20)  not null, --父菜單名稱

     cmenuuname  varchar2(20) not null,-- 子菜單名稱

     cid       number(4)   references t_menu(fid)  --子id  外鍵約束

 

 

 )

 

 select  *  from   t_menu

 

 

 

 

 

 

-- oracle序列機制   自增長機制

create  sequence   seq_stus

start  with  1

increment  by 1

nocache;

 

--查詢序列的當前值  dual是個系統表

select   seq_stus.currval  from  dual;

 

drop  sequence  seq_stus

 

 

 

 

insert  into  t_stus  values(seq_stus.nextval,'李欣');

commit;

 

select   *  from   t_stus

 

delete  from  t_stus

 

--mysql自增長    auto_increment 從起始編號為1,每次增加1.

--sqlserver自增長  identity(10,1)

 

 

 

 

-- oracle內置函數

 

--to_date(參數1,參數2),把一個字元串類型的日期轉換成date類型,

--參數2,按照什麼日期格式

 

--length() 獲取結果的長度

 

--to_char()轉換成字元串類型

select   to_char(sysdate,'yyyy')

-to_char(e.ebirthday,'yyyy')  age

  from   t_employees  e

 

-- 拼接字元串concat()

-- 輸出一段描述"胡瓜的職位是什麼"

select concat(concat(e.ename,'職位是:'),e.ejob) 描述

 from  t_employees  e  where e.ename='胡瓜';

 

 

-- ||連接

select  e.ename||',職位是'||e.ejob  from   t_employees e

 

--nvl()函數,取值為null,給預設值

select *   from   t_employees e  for  update

 

--增加獎金欄位

alter  table  t_employees  add  ecomm  number(5,2)

 

-- 算出每個員工的收入

select  e.ename,e.esalary+e.ecomm    from   t_employees  e

select  e.ename,e.esalary+nvl(e.ecomm,0)    from   t_employees  e

 

 

--substr()截取

alter  table  t_employees  add  ephone  char(11) 

--號段

select  substr(e.ephone,0,3) from

 t_employees  e  where  e.ename='胡瓜'

 

 --to_number()轉換成數值的函數

 

 

--聚合函數 count(),max(),min(),sum(),avg()

select   count(*)  from  t_employees

select   max(e.esalary)  from  t_employees  e

 select   min(e.esalary)  from  t_employees  e

 select   avg(e.esalary)  from  t_employees e

--事務?????

--手動事務,自動事務,可以設置

 

 

-- 3查詢技術  70%

 

-- 3.1 條件查詢   where關鍵字

 

-- 查詢姓名是李欣的所有信息

select   *  from  t_employees  e  where e.ename='李欣'

 

--查詢姓名是李欣,密碼是12345的這個用戶是不是合法用戶

select  count(*) from  t_employees  e  where e.ename='李欣'  

and e.epwd='1111'

 

select  *  from  t_employees  e  where  e.esex='男'

or  e.ename='李欣'

 

--3.2  比較查詢 >,<,>=,<=,!= <>

select  * from  t_employees e  where e.esalary!=5000

 

select  * from  t_employees e  where e.esalary<>5000

 

 

--3.3  模糊查詢

 

--查詢姓李的人員的信息

select   * from  t_employees  e  where  e.ename  like '李%'

 

--查詢姓李的人員的,但是是兩個字的人員信息

select   * from  t_employees  e  where  e.ename  like '李__'

 

--3.4  排序

 

--asc  desc

 

select   *  from  t_employees  e  order  by e.esalary asc

select   *  from  t_employees  e  order  by e.esalary desc

 

--3.5 分組

 

--group by  統計就是和聚合函數在一起使用。

 

--統計這個單位的男女 性別數量  分組條件是明確

select   e.esex,count(e.esex)

 from   t_employees  e  group  by e.esex

 

 --

 select  *  from    t_employees  for  update

 -- 統計每個年齡員工的數量 select  count(*),   分組條件是計算的

 select  count(*),

 to_char(sysdate,'yyyy')-to_char(e.ebirthday,'yyyy') age

 from   t_employees  e  group by

 to_char(sysdate,'yyyy')-to_char(e.ebirthday,'yyyy')

 

 --統計每個職位的數量

 select  e.ejob,count(*)

 from   t_employees  e  group  by  e.ejob

 

 --統計學歷,統計籍貫

 

 --統計每個年齡數量大於1  分組後帶有限制條件

  select  count(*),

 to_char(sysdate,'yyyy')-to_char(e.ebirthday,'yyyy') age

 from   t_employees  e  group by

 to_char(sysdate,'yyyy')-to_char(e.ebirthday,'yyyy')

 having count(*)>1

 

 --統計每個年齡數量,數量按升序(先分組,後排序)分組帶排序

   select  count(*),

 to_char(sysdate,'yyyy')-to_char(e.ebirthday,'yyyy') age

 from   t_employees  e  group by

 to_char(sysdate,'yyyy')-to_char(e.ebirthday,'yyyy')

  order  by count(*)

 

 

-- 子查詢  一個查詢的結果作為另外一個查詢的條件

 -- 找出工資最高的人的姓名

 select   *  from   t_employees

 

 select  *  from  t_employees  e where e.esalary=

 (select  max(e.esalary)  from   t_employees e)

 

 

--3.6 in ,not in ,between and  ...any  all關鍵字

 

-- =只能等於一個值

select   * from  t_employees  e  where e.esalary=10000.88

-- in可以是多個值

select   * from  t_employees  e  where e.esalary

in(10000.88,5000.00)

 

select   * from  t_employees  e  where e.esalary

not  in(10000.88,5000.00)

 

select  * from  t_employees e  where  e.esalary   between  4000

and  20000;

 

select  * from   t_employees e  where   e.esalary >=4000

and e.esalary <=20000

 

--any  >是比最小的大的信息,<是比最大的小信息

select  e.esalary,e.ename  from t_employees e  where e.esalary<any

(select  e.esalary    from t_employees  e where e.ejob='職工')

 

--all  >是比最大的大的信息,<是比最小的小信息

select  e.esalary,e.ename  from t_employees e  where e.esalary < all

(select  e.esalary    from t_employees  e where e.ejob='職工')

 

select   *  from  t_employees  for  update

 

 

-- 查詢1991年到1999年出生的員工的信息

 

select   *  from  t_employees

 

select   *  from  t_employees  e 

where  to_number(to_char(e.ebirthday,'yyyy'))

  between 1991 and  1999

 

 

 

 

--****

 

 

insert  into  t_stus   values(seq_stus.nextval,

'李二',default,'男')

 

 

select  *  from   t_employees  for  update

 

 

--- oracle高級查詢技術

 

-- 1.子查詢

 

-- 邏輯,就是從一個條件出發去找關聯的條件。

 

-- 一個查詢的結果作為另一個查詢的條件

 

-- 找出員工工資最高人的信息

select  *   from   t_employees  e  where e.esalary  in

(select  max(e.esalary)   from  t_employees  e)

 

--找出和李欣職位不同的員工的信息

 

select  *   from  t_employees  e  where e.ejob!=

(select  e.ejob  from  t_employees  e  where e.ename='李欣')

 

 

--找出比員工平均工資高的員工的信息

select  *   from  t_employees  e  where e.esalary>

(select  avg(e.esalary)  from   t_employees  e)

 

--找出收入最高的員工的信息

 

select  *  from   t_employees  e where e.esalary+nvl(e.ecomm,0)=

(select   max(e.esalary+nvl(e.ecomm,0))  from   t_employees  e )

 

 

--oracle分頁查詢 局限性 ,一條sql語句對應一張表,造成SQL冗餘

 

--oracle特殊的列,偽列  rownum ,它始終在第一行,不能移動

 

select  rownum, e.*  from  t_employees  e

 

--查詢前三條的數據

select rownum, e.*    from  t_employees  e  where rownum<=3

 

select rownum, e.*    from  t_employees  e  where rownum<=2

 

-- 查詢第2條到第4條之間的數據,查詢出是空的

select rownum, e.*    from  t_employees  e  where rownum>=2

and rownum<=4;

 

select rownum, e.*    from  t_employees  e  where rownum

between 2  and  4

 

--rownum始終在第一行,導致你查詢出來的是空的。

 

-- 查詢第2條到第4條之間的數據

--通過臨時結果集過渡查詢

select  *  from  

(select rownum  rm,e.*  from  t_employees  e  where rownum<=4)  tmp

where  tmp.rm>=2

 

select rownum, e.*    from  t_employees  e

 

--分頁查詢

 

-- 最大的編號:<=第幾頁*每頁條數

--起始編號:>(第幾頁-1)*每頁條數

 

select  *  from  t_employees  e

 

--每頁的條數是2條

--第一頁數據  第一頁,2條  out:結果集

select  *   from  

(select   rownum  rm,e.* from  t_employees  e  where  rownum<=1*2)

tmp  where tmp.rm>(1-1)*2

 

 

--第二頁數據

select  *  from  

(select  rownum  rm,e.*   from  t_employees  e  where  rownum<=2*2)

tmp  where tmp.rm>(2-1)*2

--第三頁數據

 

select  *  from  

(select  rownum  rm,e.*   from  t_employees  e  where  rownum<=3*2)

tmp  where tmp.rm>(3-1)*2

 

 

-- 在實際的項目中的一個

--局限性 ,一條sql語句對應一張表,造成SQL冗餘 ,

--比如;100張表需要100個sql嗎?

 

 

 

--2.集合查詢

 

--集合查詢

-- 多個結果集的查詢

-- 工資大於3000的和職位是組長的兩個查詢結果的合併,過濾重覆

-- 合併不過濾重覆,查詢的兩個結果合併

select  e.ename,e.esalary   from 

t_employees  e  where e.ejob='組長'

union all

select e.ename,e.esalary     from  t_employees  e 

where e.esalary>3000

 

--合併過濾重覆

select  e.ename,e.esalary   from 

t_employees  e  where e.ejob='組長'

union

select e.ename,e.esalary     from  t_employees  e 

where e.esalary>3000

 

--交集,兩個查詢結果集都有的

select  e.ename,e.esalary   from 

t_employees  e  where e.ejob='組長'

intersect

select e.ename,e.esalary     from  t_employees  e 

where e.esalary>3000

 

--差集

select  e.ename,e.esalary   from 

t_employees  e  where e.ejob='組長'

minus

select e.ename,e.esalary     from  t_employees  e 

where e.esalary>3000

 

--3.decode()函數查詢  分支查詢

 

select  *   from 

t_employees

 

--科長工資加1.2倍,組長工資加1.1倍,其它職位保持原有,

--請輸出加薪後的所有的員工的

--信息

select  e.ename,e.ejob,e.esalary,

decode(e.ejob,'科長',e.esalary*1.2,

'組長',e.esalary*1.1,

esalary)  加薪後的工資

from  t_employees  e

 

-- 等同於case..when

select  e.ename,e.ejob,e.esalary,

case e.ejob when '科長' then e.esalary*1.2

            when '組長' then e.esalary*1.1

            else  e.esalary  end

              

加薪後的工資       

from  t_employees  e

 

--4.多表查詢(2表查詢,第三範式)

 

--之前講的都是單表查詢,進入到多表(>1)查詢

 

--第三範式

-- 表中的列只能參照一個主鍵欄位

 

-- 員工表 員工id,員工姓名,部門名稱,部門id, 拆分形成兩個實體表

 

--實體表之間的關係,主要有三種:

--1.一對一關係  員工表和角色表

--2.一對多關係   部門表和員工表  商品分類表和商品表

--3.多對多關係    學生和課程表(中間關係表,第三方表,成績表)

          

--實體表之間的關係圖,ER圖

 

--這個關係的定義是根據現實的業務來決定的。

select   *  from  t_employees

 

--建立一個部門表  部門和員工表之間的關係是1對多

create  table  t_depts

(

    did  int   primary  key,

    dname  varchar2(20) not null,

    daddress  varchar2(50),

    dphone   char(11)  not null

 

)

 

create  sequence  seq_depts

start with  10

increment  by 2

nocache;

 

 

insert  into  t_depts 

values(seq_depts.nextval,'質量部','南京江北新區','13913321089');

insert  into  t_depts 

values(seq_depts.nextval,'技術部','南京江寧區','13913321086');

insert  into  t_depts 

values(seq_depts.nextval,'人力資源部','南京鼓樓區','13913321085');

commit;

 

 

select  *   from   t_depts  for  update

 

select  *  from  t_employees  for  update

 

-- 員工和部門之間是有關係的

 

alter  table t_employees  add  deptid   int;

 

 

--外鍵約束????????????

alter  table  t_employees  add  constraints  fk_emp_depts

 

 

-- 表的設計,軟體核心來自於數據

 

-- 查詢這兩張表的數據  笛卡爾積 表1*表2

select  *  from  t_employees,t_depts

 

--等值連接

select   *  from    t_employees  e,t_depts  d

where e.deptid=d.did

 

 

--內連接查詢inner  join  

select   *  from    t_employees  e  inner  join  t_depts  d

on e.deptid=d.did

 

-- 查詢員工李欣的部門名稱

select  d.dname,e.ename from  t_employees   e  inner  join 

 t_depts  d

on   e.deptid=d.did  where  e.ename='李欣'

 

--子查詢 的效率比內連接查詢要低

select  d.dname  from  t_depts  d where d.did=

(select  e.deptid   from  t_employees   e  where e.ename='李欣')

 

--左連接

select  d.dname,e.ename from  t_employees   e  left  join 

 t_depts  d

on   e.deptid=d.did 

 

 

--右連接

select  d.dname,e.ename from  t_employees   e  right  join 

 t_depts  d

on   e.deptid=d.did 

 

 

--全連接

 

select  d.dname,e.ename from  t_employees   e  full  join 

 t_depts  d

on   e.deptid=d.did

 

 

--

select   *  from  t_depts

 

--  統計技術部人員的工資的總和

 

select   sum(e.esalary) 工資總和  from  t_depts  d  inner  join  t_employees e  on d.did

=e.deptid  where d.dname='技術部'

 

--  統計每個部門的人員的數量

select   count(e.ename) 數量, d.dname from  t_depts  d 

left  join  t_employees e  on d.did=e.deptid 

  group  by  d.dname

=e.deptid

 

--統計每個部門的人員的數量大於1的信息  group  by 限制條件  having

 

select   count(e.ename) 數量, d.dname from  t_depts  d 

left  join  t_employees e  on d.did=e.deptid 

group  by  d.dname

having count(e.ename)>1

  

 --統計每個部門的人員的數量按降序排列

select   count(e.ename) 數量, d.dname from  t_depts  d 

left  join  t_employees e  on d.did=e.deptid 

group  by  d.dname   order by   count(e.ename)  desc

 

 

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

 

 

---pl-sql塊

--塊:一組SQL語句在一起運行,解決複雜的業務邏輯。

-- 是不能夠被編程語言所調用  java,python,c#

 

--塊的基本結構

/**

 declare

 

            ---定義的變數

 begin

  

 

             -- 一組sql語句

 

 end;

 

 

 

**/

 

 

 

/**

變數v_

變數賦值:=

 

 

**/

 

-- 計算兩個數值類型的變數的和並輸出

declare

   v_num1 number:=100;

   v_num2 number:=10;

   v_sum number;

begin

 

    

   v_sum:=v_num1+v_num2;

  

   dbms_output.put_line('計算這兩個數的和為'||v_sum);

  

end;

 

 

-- 異常處理  計算兩個數值類型的變數的商並輸出

declare

   v_num1 number:=100;

   v_num2 number:=0;

   v_sum number;

begin

 

    

   v_sum:=v_num1/v_num2;

  

   dbms_output.put_line('計算這兩個數的和為'||v_sum);

  

--異常處理塊

exception   --捕獲異常

    when  others  then

        dbms_output.put_line('v_num2這個數作為除數不能為零');

  

end;

 

-- 流程式控制制語句

-- 一個數判斷是奇數還是偶數,並輸出信息

 

declare

v_num  number:=22;

 

begin

 

  -- oracle不支持%取模,取模函數mod()

  if   mod(v_num,2)=0  then

  

       dbms_output.put_line('v_num這個數是偶數');

 

  else

       dbms_output.put_line('v_num這個數是奇數');

  end  if;

 

end;

 

 

--優化

declare

v_num  number:=22;

v_str  varchar2(100);

begin

 

  -- oracle不支持%取模,取模函數mod()

  if   mod(v_num,2)=0  then

   v_str:='v_num這個數是偶數';

     

 

  else

     v_str:='v_num這個數是奇數';

      

  end  if;

 dbms_output.put_line(v_str);

end;

 

-- 查詢李欣這個員工的性別,如果是男的,獎金加1000,

--如果是女的,獎金加500,

-- 輸出他現在的收入輸出

/**

1.賦值:=  直接給變數賦值

2.從sql語句查詢的結果進行賦值。2.1查詢出來的是一個值,into

2.2 如果是多個值,不能用into,要用游標遍歷

 

**/

 

 

declare

v_esex  t_employees.esex%type;  --這個變數的類型參照表中的欄位類型

v_usaraly  t_employees.esalary%type;

v_sum  number(10,2);

begin

 

  --1.查詢李欣這個員工的性別

  select  e.esex   into   v_esex

   from  t_employees  e  where e.ename='李欣';

  

   --2.判斷是男還是女

  

   if   v_esex='男'   then

    

       v_usaraly:=1000;

  

   else

    

      v_usaraly:=500;

  

   end  if;

  

   --執行更新

   update   t_employees  e  set  e.esalary=e.esalary+v_usaraly

   where e.ename='李欣';

  

   commit;

  

  

   -- 查詢出現在的收入

  select  e.esalary+nvl(e.ecomm,0)  into  v_sum   from  t_employees  e where e.ename='李欣';

 

 

  dbms_output.put_line('李欣這個員工的性別是:'||v_esex||',他現在的收入為:'||v_sum);

  --select  e.ename from  t_depts  d  inner join  t_employees  e

  -- on d.did=e.deptid  where d.dname='質量部'

 

end;

 

 

-- 查詢李欣的部門名稱,如果是質量部,加1000,如果是技術部加2000,

--如果是人力資源部加500,其它部門加100

 

declare

v_dname  t_depts.dname%type;

v_ecomm   t_employees.ecomm%type;

 

begin

 

 -- 李欣的部門名稱

 select  d.dname   into   v_dname  from  t_employees e   inner  join  t_depts d

 on e.deptid=d.did  where e.ename='李欣';

 

 if v_dname='質量部' then

  

 v_ecomm:=500;

  

 elsif  v_dname='技術部' then

 

   v_ecomm:=600;

 elsif v_dname='人力資源部'  then

 

   v_ecomm:=200;

 else

      v_ecomm:=100;

 

 end   if;

 

 

    update   t_employees  e  set  e.ecomm=e.ecomm+v_ecomm

   where e.ename='李欣';

  

   commit;

 

end;

 

 

-- 迴圈結構

 

--1.100之和並判斷是奇數還是偶數

--  for  loop

declare

 

v_sum  number:=0;

 

begin

 

for v_i  in 0..100  loop

 

    v_sum:=v_sum+v_i;

   

end  loop;

 

  dbms_output.put_line('和為'||v_sum);

 

end;

 

--while loop

 

 

declare

v_i  number:=0;

v_sum  number:=0;

 

begin

 

   while v_i<=100  loop

    

      v_sum:=v_sum+v_i;

     

      v_i:=v_i+2; --改變迴圈變數的值

   end  loop;

 

dbms_output.put_line('和為'||v_sum);

 

end;

 

 

--迴圈結構使用

 

create  table   t_users

(

 

   id  int  primary key,

   tname  varchar2(20),

   tsex   char(6)

 

)

 

create  sequence  seq_users

start with  1

increment  by 1

nocache;

 

select  * from  t_users

 

--for迴圈批量數據

declare

begin

 

for  v_i  in 1..10000  loop

 

   if mod(v_i,2)=0  then

    

      insert  into  t_users  values(seq_users.nextval,'李'||v_i,'男');

     

   else

       insert  into  t_users  values(seq_users.nextval,'王'||v_i,'女');

  

   end  if;

 

end  loop;

 

commit;

end;

 

--while迴圈批量數據

declare

v_i  number:=1;

begin

 

while  v_i<=1000  loop

   insert  into  t_users  values(seq_users.nextval,'李'||v_i,'男');

 

v_i:=v_i+1;

 

 

end loop;

 

commit;

 

end;

 

---into是只能附一個值

-- 如果是多個值,就是游標,就是結果集,分為;cursor(顯示游標),隱式游標

 

-- 查詢員工表的中的數據,並輸出每個人的姓名和性別

-- while..loop

declare

   --定義一個顯示游標

   cursor  v_datas is select  *  from  t_employees;

   -- 定義一行

   v_linedatas  t_employees%rowtype;

 

begin

 

   

   --打開這個游標

   open  v_datas;

  

   --遍歷游標

   fetch  v_datas  into v_linedatas; --遍歷第一行

  

     while  v_datas%found  loop -- 如果有數據進入迴圈體

       

        dbms_output.put_line(v_linedatas.ename||',性別是:'||v_linedatas.esex);

      

         fetch  v_datas  into v_linedatas;--移動到下一行

     end  loop;

  

  

   -- 關閉游標

   close  v_datas;

end;

 

-- for..loop

 

declare

   --定義一個顯示游標

   cursor  v_datas is select  *  from  t_employees;

 

begin

 

   for v_linedatas in v_datas loop

  

    dbms_output.put_line(v_linedatas.ename||',性別是:'||v_linedatas.esex);

   end  loop;

  

   -- 關閉游標

end;

 

-- 隱式游標

 

-- 查詢質量部員工的性別,是男加1000,是女加5000

 

declare

v_sex  t_employees.esex%type;

v_comm  t_employees.ecomm%type;

 

begin

     

   --質量部的員工的信息

  for  v_datas  in ( select  e.esex ,e.ename  from  t_employees  e   right  join  t_depts  d

   on  e.deptid=d.did  where d.dname='質量部')  loop

  

     dbms_output.put_line(v_datas.esex||v_datas.ename);

    

     if v_datas.esex='男'  then

      

       v_comm:=200;

     else

       v_comm:=50;

     end  if;

    

     --執行更新

     update  t_employees e  set e.ecomm=e.ecomm+v_comm

     where e.ename=v_datas.ename;

     commit;

  

   end  loop;

 

end;

 

 

select   *  from   t_employees

 

 

---存儲過程

 

-- 存儲(是以一個名字來存儲)+過程(過程化的語句塊)

 

-- pl-sql塊是不能夠被編程語言直接調用,只能運行在資料庫端

-- 以一個名字命名,這個名字被編程語言call,這樣形成交互

 

--預編譯,編譯一次,下次調用的話不需要再次編譯,性能好,

--能夠處理複雜的業務邏輯,

--可以有傳入和輸出參數,缺點:占用存儲空間

--sql(dml語言,調用一次編譯一次),性能沒有存儲過程好

 

--基本結構

create  or  replace  procedure   存儲過程的名字

(

 

      --傳入和輸出參數

 

)

as

 

 

 

begin

 

 

 

 

end;

 

---檢查登錄

create  or  replace  procedure   p_checklogin

(

 

      v_uname  in   varchar2, --傳入參數不需要長度

      v_pwd   in   varchar2,

      v_msg  out   varchar2

)

as

v_count  int;

 

 

begin

 

   --檢查登錄

   select count(*) into  v_count  from  t_employees  e  where e.ename=v_uname

  

   and   trim(e.epwd)=v_pwd;

  

   

   --進行判斷

   if  v_count>0 then

    

 

 

 

    v_msg:='登錄成功';

   else

    

      v_msg:='登錄失敗';

     

   end  if;

  

   --記錄

   insert  into  t_userlog  values(seq_userlog.nextval,v_uname,default,v_msg);

   commit;

  

  

end;

 

-- 變更存儲過程

 

create table  t_userlog

(

    ulid   int   primary key,

    uname varchar2(20), -- 登錄的人

    logintime  date  default  sysdate, --登錄的時間

    loginresult  varchar2(20)   --登錄的結果

 

)

 

create  sequence  seq_userlog

start  with 1

increment  by 1

nocache;

 

 

select  *  from  t_userlog

 

-- 直接返回一個結果集(不在存儲過程內部遍歷)

--**部門的員工的數量和員工的姓名

create  or  replace  procedure  p_queryempDatas

(

 

    v_dname  in  varchar2,  --部門名稱

    v_count  out  int,  --部門員工數量

    v_namedatas   out  sys_refcursor  --部門員工姓名

)

as

 

begin

 

  --1.通過部門名稱得到部門的員工的數量

  select count(e.ename)  into  v_count   from  t_employees  e

   right  join  t_depts d

  on  e.deptid=d.did  where d.dname=v_dname;

 

 

  --2.員工姓名(不在存儲過程內部遍歷)

  open  v_namedatas   for select e.ename    from  t_employees  e 

  right  join  t_depts d

  on  e.deptid=d.did  where d.dname=v_dname;

 

 

end;

 

----**部門的員工的數量和屬於這個部門的員工的性別,

--如果是男,工資加250;

--女加100;

 

 

create   or  replace   procedure  p_querydeptupdatesalary

(

   v_dname  in   varchar2,

   v_count  out  int

)

as

v_salary  t_employees.esalary%type;

begin

 

    --1.通過部門名稱得到部門的員工的數量

  --select count(e.ename)  into  v_count   from  t_employees  e

   --right  join  t_depts d

  --on  e.deptid=d.did  where d.dname=v_dname;

 

  --調用函數,減少冗餘代碼

  v_count:=f_querydeptempnum(v_dname);

 

  --2.這個部門的所有員工的信息

 

  for  v_linedatas  in (select  *     from  t_employees  e 

  right  join  t_depts d

  on  e.deptid=d.did  where d.dname=v_dname)  loop

 

  if v_linedatas.esex='男' then

   

     v_salary:=250;

   

  else

   

      v_salary:=150;

 

  end  if;

 

 

  --執行更新

  update  t_employees  e  set  e.esalary=e.esalary+v_salary

  where  e.ename=v_linedatas.ename;

 

  commit;

 

 

  end  loop;

 

 

end;

 

 

 

select  *  from  t_employees

 

-- 自定義函數  特殊的存儲過程

-- 自定義函數  1.關鍵字function  2.只能返回一個值

create   or  replace  function  f_querydeptempnum

(

   v_dname  in  varchar2

)

return int --切記這個地方不能加;

as

 

v_count  int;

begin

 

    select  count(e.ename)  into  v_count  from  t_employees e

    right  join  t_depts  d  on  e.deptid=d.did

    where  d.dname=v_dname;

   

   

    return v_count;

 

end;

 

-- 查詢一個表t_employees的條數  如果系統中的表很多,這樣會造成冗餘

create   or  replace  function  f_queryempcount

return  int

as

 

v_count  int;

begin

 

    select  count(*)   into  v_count from  t_employees ;

    return  v_count;

 

end;

 

--動態sql

 

-- 一個值

create   or  replace  function  f_querytablecount

(

 

   v_tableName   in  varchar2

)

return  int

as

 

v_sql varchar2(1000);

 

v_count  int;

begin

 

   v_sql:='select   count(*)  from  ' ||v_tableName;

  

  

   -- 執行這個動態sql,是一個值

   execute immediate  v_sql  into v_count;

  

   return v_count;

 

end;

 

---多個值

create   or  replace  function  f_querytabledatas

(

 

   v_tableName   in  varchar2

)

return  sys_refcursor

as

 

v_sql varchar2(1000);

 

v_datas  sys_refcursor;

begin

 

   v_sql:='select   *  from  ' ||v_tableName;

  

  

    -- 執行這個動態sql,是一個結果集

    open v_datas  for v_sql;

   

    return v_datas;

   

end;

 

 

--sql語句分頁  固定2條

 

select   *  from  t_employees

 

-- sql分頁,系統大了,會造成SQL冗餘

select   * from (select  rownum  rm, 

e.* from  t_employees  e  where  rownum<=4)  tmp

where tmp.rm>2

 

 

--存儲過程分頁 一個存儲過程可以對系統中的表都可以分頁

-- tablename  in  表名

--pagenum   in   每頁幾條

--currentnum  in  第幾頁

--datas  out  每頁的結果集

--count  out  總條數

--pagesize  out  總頁數

create   or   replace    procedure   p_pagemodel

(

 

    v_tablename  in   varchar2,

    v_pagenum   in    int,

    v_currentnum  in  int,

    v_datas  out  sys_refcursor,

    v_count   out   int,

    v_pagesize  out  int

 

)

as

v_endindex  int:= v_currentnum*v_pagenum;

 

v_startindex  int:=(v_currentnum-1)*v_pagenum;

 

v_sql  varchar2(1000);

begin

 

   --1.構建總的條數動態sql

   v_sql:='select   count(*)   from     '||v_tablename;

  

   --2.執行動態sql

   execute  immediate  v_sql  into v_count;

  

   --3.獲取總頁數

   if   mod(v_count,v_pagenum)=0  then

    

     v_pagesize:=v_count/v_pagenum;

    

   else

      --除不盡

     v_pagesize:=floor(v_count/v_pagenum)+1;

    

   end  if;

  

   --獲取分頁結果集

   v_sql:='select   *   from  '||'(select  rownum  rm, e.* from  '||v_tablename||

    '   e  where  rownum<='||v_endindex||')   tmp' ||' where tmp.rm>'||v_startindex;

   

   dbms_output.put_line(v_sql);

  

   --執行動態sql,返回的是一個結果集

   open v_datas  for v_sql;

   

end;

 

-- 面試的時候,什麼是事務

--jdbc 事務  自動事務

--hiernate事務

--mybatis事務

 

--spring事務

 

--python事務  手動事務 

 

--  rollback回滾事務  commit提交事務  savepoint 設置事務保存點

--資料庫事務

--事務就是一個工作單元,所謂的工作單元,就是不可分割的一個或多個SQL

-- (insert ,update,delete)

 

--秦日霞借錢1000給李欣,並記錄日誌。

select  *  from  t_employees

 

 

--秦日霞借錢1000給李欣

--記錄日誌

create  or   replace  procedure   p_operatorsalary

(

 

   v_rname  in  varchar2,

   v_tname  in  varchar2,

   v_money  in  number,

   v_msg   out  varchar2

 

)

as

begin

 

    -- 1.先把借錢人的錢扣掉

    update  t_employees  e  set

    e.esalary=e.esalary-v_money  where e.ename=v_rname;

   

    --2.加上給借錢人

     update  t_employees  e  set

    e.esalary=e.esalary+v_money  where e.ename=v_tname;

   

    --設置一個事務保存點  給個名字

   

   

    savepoint  a;

   

    --3.記錄日誌

    insert  into  t_userlog 

    values(seq_userlog.nextval,v_tname,'1997-12-30','借錢');

   

    commit;

  

exception

 

when  others  then

  rollback to a;  --回滾到事務保存點a,提交

  commit;

  

end;

 

 

select   *   from  t_userlog

 

 

 

 

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

 

--索引,job(定時任務),視圖,觸發器

 

-- 索引

-- 怎麼來提高查詢的性能?

 

-- 1.索引   2. SQL優化

 

-- 索引就是來提高查詢的性能。

-- 打個比方來說:書的目錄 聚集索引 ;

--書的頁碼:聚集索引

 

-- 70W條的數據以上我們才考慮建立索引

 

-- 建立一張表

create  table  t_stuinfo

(

 

    suid  number(7)  primary  key,

    sname  varchar2(100),

    sbirthday  date  default  sysdate,

    ssex  char(4)

 

)

 

 

 

--載入80W條數據

 

declare

begin

   for v_i  in 1..1200000 loop

    

       if mod(v_i,2)=0  then

        

      

         insert  into  t_stuinfo  

         values(v_i,'李'||v_i,default,'男');

      

        

       else

     

  

         insert  into  t_stuinfo  

           values(v_i,'王華'||v_i,default,'女');

   

       end  if;

   end  loop;

  

   commit;

 

end;

 

delete  from  t_stuinfo

 

select  count(*)  from  t_stuinfo

 

 

select  *  from  t_stuinfo

 

-- 白盒測試 查詢  王華67001 查這個人的信息

create  or  replace  procedure  p_queryinfo

(

    v_name  in  varchar2

 

)

as

v_begintime  varchar2(1000);

v_endtime   varchar2(1000);

v_birthday t_stuinfo.sbirthday%type;

begin

 

       v_begintime:=to_char(systimestamp,'yyyy-MM-dd hh24:mi:ss.ff');

 

        select  s.sbirthday   into  v_birthday

        from   t_stuinfo s  where s.sname=v_name;

       

       

       v_endtime:=to_char(systimestamp,'yyyy-MM-dd hh24:mi:ss.ff');

     

     

      dbms_output.put_line('開始時間:'||v_begintime);

      dbms_output.put_line('接受時間:'||v_endtime);

   

end;

 

--

/**

開始時間:2018-03-23 09:29:31.490000000

接受時間:2018-03-23 09:29:31.537000000    --47000000

 

開始時間:2018-03-23 09:32:05.235000000

接受時間:2018-03-23 09:32:05.250000000    --15000000

 

--

開始時間:2018-03-23 09:32:52.942000000

接受時間:2018-03-23 09:32:52.958000000 16000000

 

 

開始時間:2018-03-23 09:33:26.529000000

接受時間:2018-03-23 09:33:26.576000000  47

**/

 

-- 建立索引

create  index    snameindex   on   t_stuinfo(sname);

 

drop  index  snameindex;

 

 

call   p_queryinfo('李966002');

 

-- job定時任務  資料庫定時任務

 

--自動化定時任務  對於表的歷史數據的一個定時清理

 

-- 1-10

 

-- t_stuinfo ,每隔1分鐘自動插入一條數據

delete  from   t_stuinfo;

commit;

 

create  sequence   seq_stuinfo

start  with 1

increment   by  1

nocache;

 

--建立一個存儲過程

create  or  replace  procedure  p_timetaskadddata

as

begin

 

  insert  into  t_stuinfo  

         values(seq_stuinfo.nextval,'李欣',default,'男');

    

  commit;

 

end;

 

 

--建立一個任務

variable  job2018  number;

 

-- 命令行視窗   提交這個定時任務

SQL> variable  job2018   number;

SQL> begin

  2  dbms_job.submit(:job2018,'p_timetaskadddata;',

  sysdate,'sysdate+1/1440');

  3  end;

  4  /

 

 

select   *   from   t_stuinfo

 

 

SQL> begin

  2  dbms_job.remove(:job2018);

  3  end;

  4  /

 

**PL/SQL procedure successfully completed

job2018

---------**


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • [TOC] MyBatis簡單介紹 MyBatis是一個持久層框架,使用簡單,學習成本較低。可以執行自己手寫的SQL語句,比較靈活。但是MyBatis的自動化程度不高,移植性也不高,有時從一個資料庫遷移到另外一個資料庫的時候需要自己修改配置。 一個Mybatis最簡單的使用列子如下: 從配置文件(通 ...
  • 題目描述 設定有一個資料庫,裡面有4張表: 學生表(student) 課程表(course) 成績表(score) 教師信息表(teacher) 表結構如下: 表一_學生表(student) 屬性名數據類型含 義 sno int 學號(主鍵) sname varchar 學生姓名 ssex varc ...
  • 修改分區表主鍵時報錯: 在行: 2 上開始執行命令時出錯 -alter table KC23 modify AAZ210 VARCHAR2(50)錯誤報告 -SQL 錯誤: ORA-14061: 不能更改索引分區列的數據類型或長度14061. 00000 - "data type or length ...
  • 資料庫加鎖是修改哪一條加鎖,還是在頁上加鎖,還是在表上加鎖,資料庫來決定 如果你更改的是兩條記錄,就在兩條記錄上加鎖,如果你更改的是很多條,這個時候資料庫一看一條一條加鎖太麻煩,給整個頁加鎖更省事,或者給整個表加鎖更加省事 加鎖的級別越大,資料庫越省事,資料庫越省事,併發性越差,修改一條記錄如果給表 ...
  • 問題: 1.在頁面存入中文後亂碼,從前端從後臺發現數據未發生異常,發現是存入資料庫後亂碼; 經查詢該欄位為text欄位,存入中文會亂碼 如圖 解決辦法: 1.將text轉為varchar或nvarchar,再修改為ntext alter table ReportSpec alter column c ...
  • Date:2019-11-12 讀前思考: 面試官會問什麼樣的問題? 所問的問題背後真實的套路是什麼? 喜歡問Redis哪些問題? 如何順暢回答面試問的問題?弔打面試官。 1、什麼是Redis? 2、Redis相比memcached有哪些優勢? 3、Redis支持哪幾種數據類型? 4、Redis的緩 ...
  • oracle 線上用戶老是被鎖: 1,查明所有的用戶哪些被鎖了 SQL> select username,account_status,lock_date from dba_users; USERNAME ACCOUNT_STATUS LOCK_DATE USER1 OPEN USER2 OPEN ...
  • SYS用戶是Oracle中許可權最高的用戶,而SYSTEM是一個用於資料庫管理的用戶。在資料庫安裝完之後,應立即修改SYS,SYSTEM這兩個用戶的密碼,以保證資料庫的安全。 安裝完之後修改密碼方法 cmd命令行下輸入 sqlplus / as sysdba; 法1.SQL>alter user sy ...
一周排行
    -Advertisement-
    Play Games
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...