Oracle 基礎

1、  Oracle 基礎

 

1.  Oracle 用戶管理

--Oracle 用戶管理
--1.建立帳戶 --建立用戶 create user scott identified by hello;
--修改密碼
alter user scott identified by root;
--忘記密碼
--cmd 輸入命令:
sqlplus /nolog
--輸入命令:
conn /as sysdba
--輸入命令:alter user
要修改的用戶名 identified by 新的密碼;
--2.維護帳戶 --賦予權限語法: grant 權限或角色名 to 用戶名; grant connect to scott; --賦予數據庫登錄鏈接權限 grant resource to scott; --賦予資源操縱權限 grant dba to scott; --賦予 dba 權限 --刪除權限語法: revoke 權限或角色名 from 用戶名; revoke dba from scott; --3.刪除帳戶 drop user scott;

 

2.  Oracle 二維表管理

--Oracle 二維表管理

  --1.Oracle 二維表的建立
    --建立表的同時添加約束
      --主鍵約束
      --非空約束
      --檢查約束
      --惟一約束
      --外鍵約束
  
    --建立表 
    varchar2(len) --len 表示字符的最大長度,實際內存根據字符長度大小分配
        --特色:動態分佈存儲空間,節省空間
    varchar(len) --直接分配最大長度的儲存空間
        --特色:存儲效率高於 varchar2
create table student( sno number(10), --primary key, sname varchar2(100) not null, sage number(3), --check(sage<150 and sage>0) ssex char(4), sfav varchar2(500), sbirth date, sqq varchar2(100), --unique constraints pk_student_sno primary key(sno), constraints ck_student_sage check(sage<150 and sage>0), constraints un_student_sqq unique(sqq) );

--刪除表
drop table student; ................................................................................... --2.添加約束 --1.添加主鍵,主鍵特色:非空惟一 --添加方法 直接在建立表字段後使用 primary key 或者 constraints pk_表名_字段名 primary key(字段名) 或者 alter table 表名 add constraints pk_表名_字段名 primary key(字段名);
--刪除方法 alter table 表名 drop constraints 主鍵約束名; --2.添加非空約束 --添加方法 直接在建立表字段後使用 not null 或者 constraints ck_表名_字段名 check(字段名 is not null) 或者 alter table 表名 add constraints ck_表名_字段名 check(字段名 is not null);
--刪除方法 alter table 表名 drop constraints 非空約束名; --3.添加檢查約束
--添加方法

直接在建立表字段後使用 check(sage<150 and sage>0) 或者 constraints ck_student_sage check(sage<150 and sage>0) 或者 alter table student add constraints ck_student_sage check(sage<150 and sage>0);
--刪除方法
alter table 表名 drop constraints 檢查約束名;
--4.添加惟一約束 --添加方法
直接在建立表字段後使用 unique 或者 constraints un_student_sqq unique(sqq) 或者 alter table student add constraints un_student_sqq unique(sqq);
--刪除方法
alter table 表名 drop constraints 惟一約束名;
--5.添加外鍵 --關鍵字:references --概念:當一張表(子表)的某個字段的值須要依賴另一張表(父表)的某個字段的值,則使用外鍵約束
--做用:當在子表中插入的數據在父表中不存在,則會自動報錯
--外鍵選取:通常選取父表的主鍵做爲子表的外鍵 --添加方法 直接在建立表字段後使用 references 父表名(字段) 或者 constraints fk_子表名_字段名 foreign key(字段名) references 父表名(字段名) 或者 alter table 子表名 add constraints fk_子表名_字段名 foreign key(字段名) references 父表名(字段名);
--刪除方法
alter table 子表名 drop constraints 外鍵約束名; --外鍵的缺點 --沒法直接刪除父表數據,除非級聯刪除 --級聯刪除:在添加外鍵約束時,使用關鍵字 on delete cascade --使用:當刪除父類數據時,自動刪除子表相關全部數據 --缺點:沒法保存子表歷史數據 --使用關鍵字 on delete set null --刪除父表數據時,將子表的依賴字段的值設爲 null --注意:子表依賴字段不能添加非空約束,否則矛盾 ................................................................................... --3.Oracle 二維表的維護
--1.添加新的字段 --語法:alter table 表名 add 字段名 類型; alter table student add sphone number(11);
--2.修改原有字段 --修改字段類型:modify --語法:alter table 表名 modify 字段名 新類型; alter table student modify sphone varchar2(100);
--修改字段名,基本不用 --語法:alter table 表名 rename column 舊字段名 to 新字段名;
alter table student rename column sphone to phone;
--刪除字段:drop column --語法:alter table 表名 drop column 字段名;
alter table student drop column phone;
--3.修改表名 rename student to student2;
--4.查看錶結構 打開命令窗口,輸入命令:desc student;

 

3.  Oracle 二維表的增刪改 & 備份

--Oracle 二維表的增刪改 & 備份
  --注意:增刪改的 SQL 執行完畢後,不會立馬進行數據的寫入,還需手動對數據進行提交(Commit),若是數據有問題能夠回滾(Rollback)
  
  --1.增長數據
    --語法:insert into 表名(字段名, 字段名, 字段名, ...) values(值1, 值2, 值3, ...);
      --主鍵必須給值,容許爲空的字段能夠不給值
      --值和字段名必須一一對應
      --若是是全字段插入,能夠省略字段名部分,即 insert into 表名 values(值1, 值2, 值3, ...);
    insert into dept(deptno, dname, loc) values(1, '計算機學院', '北京');
  
  
  --2.刪除數據
--刪除一行記錄
--語法:delete from
表名 where 條件;

--刪除表中全部記錄 --語法:delete from 表名; --truncate table 表名; 刪除表中的全部記錄,效率比 delete 高 --3.更新數據 --語法:update 表名 set 字段名 = 新的值, 字段名 = 新的值, ... where 條件; --4.數據的備份 --注意:只會備份表結構和表的數據,約束不會備份,好比主鍵沒有設置 --表級別備份 --所有備份:create table 新的表名 as select * from 表名; create table deptBak as select * from dept; --部分備份 create table deptBak as select deptno, dname from dept; --數據總體插入 --insert into 表名2 select * from 表名1; --注意:表1和表2的表結構要一致,即字段數量一致,類型一致

 

4.  單表查詢

--單表查詢學習

   --1.查詢表的全部數據:select * from 表名;
   select * from emp;
--2.查詢表中的指定字段的值:select 字段名1,字段名2, ... from 表名; select empno1,empno2 from emp;
--3.給查詢結果中的字段使用別名 --在字段名後使用:字段名 as "別名"; --注意:as 關鍵字能夠省略不寫,別名中沒有特殊字符雙引號也能夠省略不寫 select empno 員工編號,job as 工做 from emp; --4.鏈接符:字段名 || '字符' || 字段名 ||,... from 表名; --注意:拼接好的字段名在結果集中做爲一個新的字段顯示,可使用別名優化顯示 --5.去除重複,使用 distinct 去除行重複,即兩行數據徹底相同取其一 select distinct job,mgr from emp; --6.排序:order by 字段名 desc降序 / asc升序(默認) --多字段排序(先按字段1排序,若是相同則按照字段2排序):order by 字段名1,字段名2,... desc降序 / asc升序(默認) select * from emp order by empno desc; select * from emp order by empno1,empno2; --7.使用 where 條件查詢 --注意:在 where 中不能出現多行函數 --語法:select 字段名,.. from 表名 where 篩選條件; --單篩選條件 --使用運算符進行篩選 =, >, <, >=, <=, <> --多篩選條件 --在 where 子句中使用關鍵字 --and "與",and 的優先級比 or 更高 --or "或" --模糊查詢 like, not like -- % 表示任意多個的任意字符 select * from student where sname like '%s%'; --'%s%'包含s, '%s'以s結尾, 's%'以s開頭, '_s%'第二個字符是s select * from student where sname like '%/_%' escape '/'; --escape 把普通字符轉爲轉譯字符,轉譯字符可使得特殊字符轉換爲普通字符 --is null --is not null --in --between 100 and 200

 

5.  Oracle 函數

--Oracle 函數學習(單行函數,多行函數,轉換函數,其它函數)

  --1.單行函數:不改變真實數據,只是修飾顯示
    --語法:select 字段名, 函數名(字段名),... from 表名;
    
    --1.字符函數
      length(字段名)
      initcap(字段名) 字段名內容首個字母大寫
      lower(字段名)
      upper(字段名)
      ltrim('hello', 'he') -->llo
      rtrim('hello', 'llo') -->he
      concat('hello', 'World') -->helloWorld  鏈接字符串
      instr('hello', 'e') -->2  所在下標
      substr('hello', 2, 4) -->ello  取子串
      replace('hello', 'l', 're') -->Herereo
       
    --2.數值函數:對數值類型的數據進行運算
      abs()
ceil()
floor()
round()
mod()
--僞表:關鍵字 dual ,不是真實存在的表,是爲了方便進行數據的驗證而臨時存在的表 select 1+2 from dual; --3.日期函數: --sysdate 如今的時間 add_months('09-9月-2018', -3); --> 09-6月-2018 next_day('09-9月-2018', '星期日'); last_day('09-9月-2018'); --> 30-9月-2018
--2.多行函數 (max, min, avg, sum, count) --做用:對查詢的數據進行統計 --注意:多行函數不能和普通字段以及單行函數混用 --語法:select 字段名, count(字段名),... from 表名; count(*) 返回表的記錄數 count(字段名) 返回非空值的數量 count(distinct 字段名) 去除重複後的字段值的數量
--3.轉換函數 --to_number() --to_char() --9 表示佔位;0 能夠進行佔位;L 表示人民幣符號;$ 表美圓符號 select to_char(123456789, 'L000,000,000,000') from dual; select to_char(123456789, '$999,999,999') from dual; --to_date() select to_date('2018-09-13','yyyy-mm-dd') from dual; select to_date('2018/09/13','yyyy/mm/dd') from dual; select to_char(to_date('2018/09/13','yyyy/mm/dd')) from dual;
--4.其它函數 nvl(字段名, 值m):若是字段值不爲 null,返回該字段值;若爲 null,則返回值 m nvl2(字段名, 處理1, 處理2):若是字段值不爲 null,執行處理1;若爲 null,則執行處理2 decode(字段名, 值1, 處理1, 值2, 處理2, 值3, 處理3, ..., 公共處理):若是字段值等於某個值,則執行對應的處理;若是都沒對應的值,則執行公共處理

 

6.  分組查詢

--分組查詢 
  --關鍵字:group by 分組字段名,分組字段名...
  --注意1:使用了分組後,在 select 語句中只容許出現分組字段和多行函數
  --注意2:若是是多字段分組,則先按照第一字段分組,而後每一個組繼續按照第二個字段繼續分組,以此類推
  --注意3:在 where 中不能出現多行函數

--查詢各工做崗位的人數
select job,count(*) from emp group by job; --查詢不一樣部門的不一樣工做崗位的人數 select deptno,job,count(*) from emp group by deptno,job order by deptno; --分組篩選 --關鍵字:having --做用:對分組後的數據篩選,容許使用多行函數 --注意:having 關鍵詞必須和分組結合使用,不容許單獨使用
--查詢不一樣部門的不一樣工做崗位的而且人數大於1的信息 select deptno,job,count(*) from emp group by deptno,job having count(*)>1 order by deptno; 錯誤寫法,在 where 中不能出現多行函數
select deptno,job,count(*) from emp where count(*)>1 group by deptno,job order by deptno; --wherehaving 的比較 --在 where 中不能出現多行函數,但 having 能夠 --均可以使用普通字段直接進行篩選,可是 where 的執行效率比 having 的高 --where 執行順序:from--> where--> group by--> select--> order by --having 執行順序:from--> group by--> select--> having--> order by --結論:在分組語句中,使用 where 進行字段級別的篩選,使用 having 進行多行函數的篩選 select deptno,job,count(*) from emp group by deptno,job having deptno>1 order by deptno; select deptno,job,count(*) from emp where deptno>1 group by deptno,job order by deptno;

 

7.  多表聯合查詢

--多表聯合查詢
  --當須要獲取的數據分佈在多張表中的狀況使用多表聯合查詢
  
  
  --SQL92 方式
--笛卡爾積:多表的笛卡爾積,結果的數量爲全部表的數量的乘積 select * from emp,dept;
--等值鏈接篩選 --概念:先作表的笛卡爾積,而後篩選,篩選條件爲等值篩選 --注意:條件爲字段的值相同來進行篩選,字段名能夠不一樣 select * from emp e,dept d where e.deptno=d.deptno;
--不等值鏈接 select * from emp e,salary s where e.sal>=s.lowsal and e.sal<=s.hightsal;
................................................................................... --SQL99 方式
--笛卡爾積:使用 cross join 關鍵字 --語法:select 內容 from 表名 cross join 表名; select * from emp cross join dept;
--篩選 --天然連接:關鍵字 natural join --語法:select 內容 from 表名 natural join 表名; --特色:底層先笛卡爾積,而後對全部同名同值字段自動進行篩選,無須添加鏈接條件,而且在結果中消除重複的屬性列
select * from emp natural join dept;

--內連接:關鍵字 inner join,可省略 inner--問題1:若是隻想對部分同名同值字段進行篩選怎麼辦?
--解決1:使用 using 關鍵字 --做用:使用指定的字段對聯合查詢的結果進行等值篩選 --注意:指定的字段必須是兩表的同名同值字段 --語法:select 內容 from 表名 inner join 表名 using(字段名,字段名,...); select * from emp inner join dept using(deptno);
--問題2:若是想對不一樣字段名但同值的字段進行篩選怎麼辦?
--解決2:使用 on 關鍵字進行自定義鏈接條件篩選(等值篩選,不等值篩選) --注意:普通篩選條件使用 where 進行篩選,不要使用 on 。好處:SQL 的可讀性變強 select * from emp inner join dept on emp.deptno=dept.no where sal>2000;
--外鏈接 --左外鏈接:left outer join
--特色:左邊表保留未符合條件的記錄,右邊表對應屬性列的值設爲 null --查詢員工姓名,工做,薪資,部門名稱及沒有部門的員工信息 select * from emp e left outer join dept d on e.deptno=d.deptno;
--右外鏈接:right outer join
--特色:右邊表保留未符合條件的記錄,左邊表對應屬性列的值設爲 null --查詢員工姓名,工做,薪資,部門名稱及沒有員工的部門信息 select * from emp e right outer join dept d on e.deptno=d.deptno;
--全外鏈接:full outer join
--特色:結果集 = 左外鏈接和右外鏈接的並集
select * from emp e full outer join dept d on e.deptno=d.deptno; ...................................................................................
--三表聯合查詢 --SQL92 實現 --查詢員工信息及部門名稱及所在城市名稱而且員工的工資大於2000或者有獎金 select * from emp e,dept d,city c where (e.deptno=d.deptno and d.loc=c.cid and e.sal>2000) or (e.deptno=d.deptno and d.loc=c.cid and e.comm is not null); order by e.sal;
--SQL99 實現 select * from emp e inner join dept d on e.deptno=d.deptno inner join city c on d.loc=c.cid where e.sal>2000 or e.comm is not null order by e.sal;

 

8.  子查詢

--子查詢學習
  --使用時機:當查詢的篩選條件依賴於另外一條查詢結果時,考慮使用子查詢
  
  
  --單行子查詢
    --查詢全部比僱員"CLARK"工資高的員工信息
    select * from emp where sal>(select sal from emp where ename='CLARK');
  
  
  --多行子查詢
    --關鍵字:any
      --查詢工資高於任意一個"攻城獅"崗位薪資的員工信息
      select * from emp where sal> any (select sal from emp where job='攻城獅');
    
    --關鍵字:all
      --查詢工資高於全部SUN的員工信息
      select * from emp where sal> all (select sal from emp where ename='SUN');
       
    --關鍵字:in 表任意存在;not in 表不存在
      --查詢部門 20 中和部門 10 中的崗位同樣的僱員信息
      select * from emp where job in (select job from emp where deptno=10) and deptno=20;

 

9.  Oracle 序列 & 索引 & 視圖

--Oracle 的序列學習
  --建立序列
    --語法:create sequence 序列名;
    --特色1:默認開始是沒有值的,也就是指針指在了沒有值的位置
    --特色2:序列名.nextval 每次執行都會自增一次,默認步長爲1
    --特色3:序列名.currval 查看當前序列的值,開始是沒有的
    --做用:做爲主鍵使用,動態的獲取主鍵值,極大的避免了主鍵衝突
    
    --建立默認序列
    create sequence cc;
    select cc.currval from dual;
    select cc.nextval from dual;
--建立自定義序列 create sequence aa; start with 5; --設置開始位置 increment by 2; --設置步長 --刪除序列 --語法:drop sequence 序列名; drop sequence cc; ................................................................................... --Oracle 的索引學習 --做用:提升查詢效率
--建立索引 --語法:create index 索引名 on 表名(字段名); --特色:顯示的建立,隱式執行
--注意:Oracle 會自動給表的主鍵建立索引
create index index_student_sno on student(sno); --刪除索引 --語法:drop index 索引名;
drop index index_student_sno; ...................................................................................
--Oracle 的視圖學習 --建立視圖 --語法:create view 視圖名 as select 對外提供的字段名,字段名,... from 真實表名; --特色1:保護真實表,隱藏重要字段的數據,保護數據 --特色2:在視圖中的操做會映射執行到真實表中 --特色3:可手動開啓只讀模式:with read only create view stu as select sno,sname,sphone from student with read only; --注意:視圖的建立必須擁有 dba 權限 --刪除視圖
--語法:
drop view 視圖名; drop view stu;

 

10.  Oracle 的分頁查詢

--Oracle 的分頁查詢
  --當表中的數量特別大的時候,若是一次性所有顯示給用戶,體驗極差,須要用分頁查詢
  --使用
    --關鍵字:rownum,Oracle 對外提供自動給查詢結果編號的關鍵字,與每行的數據無關
    --注意:rownum 只能使用小於號
    
    --查詢學生信息的第一頁數據,每頁最多5行數據
    select rownum, s.* from student s where rownum<=5;
    --查詢學生信息的第二頁數據
    select * from (select rownum r, s.* from student s where rownum<=10) where r>5; 
    --查詢學生信息的第三頁數據
    select * from (select rownum r, s.* from student s where rownum<=15) where r>10;
     
    --總結: 查詢學生信息的第 n 頁數據,每頁有 m 行數據
    select * from (select rownum r, s.* from student s where rownum<=m*n) where r>m*(n-1);

 

11.  其它

--建立用戶表
create table users(
  usid NUMBER(10) primary key,
  uname VARCHAR2(20) not null,
  upassword VARCHAR2(20) not null,
  registerdate Date not null,
  ubirth DATE,
  usex VARCHAR2(4),
  uage NUMBER(3),
  constraints ck_users_usex check(usex='' or usex='')
);

--建立微博表
create table blogs(
  bid NUMBER(10) primary key,
  usid NUMBER(10) not null,
  publisheddate DATE not null,
  btitle VARCHAR2(20) not null,
  bcontent CLOB not null,
  constraints fk_blog_uid foreign key(usid) references users(usid) 
);

--建立好友表
create table friends(
  fid NUMBER(10) not null,
  usid NUMBER(10) not null,
  adddate DATE not null,
  remark VARCHAR2(20),
  constraints fk_friends_usid foreign key(usid) references users(usid),
  constraints fk_friends_fid foreign key(fid) references users(usid)
);

--建立評論表
create table comments(
  cid NUMBER(10) primary key,
  usid NUMBER(10) not null,
  bid NUMBER(10) not null,
  comdate DATE not null,
  comcontent CLOB not null,
  constraints fk_comments_usid foreign key(usid) references users(usid),
  constraints fk_comments_bid foreign key(bid) references blogs(bid)
);

--建立留言表
create table messages(
  mid NUMBER(10) primary key,
  usid NUMBER(10) not null,
  fid NUMBER(10) not null,
  messdate DATE not null,
  messcontent CLOB not null,
  constraints fk_messages_usid foreign key(usid) references users(usid),
  constraints fk_messages_fid foreign key(fid) references users(usid)
);

--建立照片表
create table photos(
  pid NUMBER(10) primary key,
  usid NUMBER(10) not null, 
  upldate DATE not null,
  pname VARCHAR2(20) not null,
  address VARCHAR2(30) not null,
  describ VARCHAR2(60),
  constraints fk_photos_usid foreign key(usid) references users(usid)
);

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

--建立用戶序列
create sequence users_id start with 1 increment by 1; 

--新增用戶存儲過程
create or replace procedure addUsers
(
  v_usname VARCHAR2,
  v_upassword VARCHAR2,
  v_ubirth DATE,
  v_usex VARCHAR2
 )
is
  v_exister users%rowtype;
  v_uage users.uage%type := to_char(sysdate,'yyyy') - to_char(v_ubirth,'yyyy');
begin
  select * into v_exister from users where uname=v_usname;
  if(v_exister.usid>0) then
    dbms_output.put_line('該用戶名已存在,請從新輸入!');
  end if;
  exception 
    when no_data_found then
      insert into users values(users_id.nextval, v_usname, v_upassword, sysdate, v_ubirth, v_usex, v_uage);
      commit;
      dbms_output.put_line('註冊成功!');
    when others then
      dbms_output.put_line('error');
end;

--執行新增用戶存儲過程
declare
  v_usname users.uname%type := '張三';
  v_upassword users.upassword%type := 'a123456';
  v_ubirth users.ubirth%type := to_date('1995-09-01','YYYY-MM-DD');
  v_usex users.usex%type := '';
begin
  addUsers(v_usname, v_upassword, v_ubirth, v_usex);
end;

select * from users;
drop table users; 
drop sequence users_id;

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

--添加好友存儲過程
create or replace procedure addfriend
(
  v_ffid NUMBER,
  v_userid NUMBER,
  v_remark in out VARCHAR2
)
is
v_exister friends%rowtype;
v_fd friends%rowtype;
v_usname users.uname%type;
begin
  select * into v_exister from friends where fid=v_ffid and usid=v_userid;
  if(v_exister.fid>0) then
    dbms_output.put_line('已經是好友,不能重複添加!');
  end if;
  exception
    when no_data_found then
      if(length(v_remark)=0) then
        select uname into v_remark from users where usid=v_ffid;
      end if;
      insert into friends values(v_ffid, v_userid, sysdate, v_remark);
      select uname into v_usname from users where usid=v_userid;
      insert into friends values(v_userid, v_ffid, sysdate, v_usname);
      commit;
      dbms_output.put_line('添加好友成功!'); 
    when others then
      dbms_output.put_line('添加好友失敗!');
end;

--執行添加好友存儲過程
declare
v_fid NUMBER := 1;
v_userid NUMBER := 2;
v_remark friends.remark%type :='好友';
begin 
  addfriend(v_fid, v_userid, v_remark);
end;

select * from users;
select * from friends;

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

--建立留言序列
create sequence messages_id start with 1 increment by 1;

--好友留言存儲過程
create or replace procedure leaveMessage
(
  v_friendid users.usid%type,
  v_userid users.usid%type,
  v_messcontent messages.messcontent%type
)
is
  v_exister friends%rowtype;
  v_clength number := length(v_messcontent);
begin
  select * into v_exister from friends where usid=v_userid and fid=v_friendid;
  if(v_exister.fid>0 and v_clength>0) then
    insert into messages values(messages_id.nextval, v_friendid, v_userid, sysdate, v_messcontent);
    commit;
    dbms_output.put_line('留言成功!');
  else
    dbms_output.put_line('留言內容不能爲空!');
  end if;
  exception
    when no_data_found then 
      dbms_output.put_line('還不是好友,請添加後進行留言!');
    when others then
      dbms_output.put_line('error');
end;

--執行好友留言存儲過程
declare 
  v_friendid users.usid%type := 1;
  v_userid users.usid%type := 2;
  v_messcontent messages.messcontent%type := '今每天氣真好,很適合學習!';
begin
  leaveMessage(v_friendid, v_userid, v_messcontent);
end; 


select * from users;
select * from friends;
select * from messages;
drop table friends;
View Code
相關文章
相關標籤/搜索