當前位置:才華齋>IT認證>Oracle認證>

oracle的sql語句

Oracle認證 閱讀(2.17W)

Oracle WDP 全稱為Oracle Workforce Development Program,是Oracle (甲骨文)公司專門面向學生、個人、在職人員等群體開設的職業發展力課程。下面是小編整理的關於oracle的sql語句,歡迎大家參考!

oracle的sql語句

首先,以超級管理員的身份登入oracle

sqlplus sys/bjsxt as sysdba

--然後,解除對scott使用者的鎖

alter user scott account unlock;

--那麼這個使用者名稱就能使用了。

--(預設全域性資料庫名orcl)

1、select ename, sal * 12 from emp; --計算年薪

2、select 2*3 from dual; --計算一個比較純的資料用dual表

3、select sysdate from dual; --檢視當前的系統時間

4、select ename, sal*12 anuual_sal from emp; --給搜尋欄位更改名稱(雙引號 keepFormat 別名有特殊字元,要加雙引號)。

5、--任何含有空值的數學表示式,最後的計算結果都是空值。

6、select ename||sal from emp; --(將sal的查詢結果轉化為字串,與ename連線到一起,相當於Java中的字串連線)

7、select ename||'afasjkj' from emp; --字串的連線

8、select distinct deptno from emp; --消除deptno欄位重複的值

9、select distinct deptno , job from emp; --將與這兩個欄位都重複的值去掉

10、select * from emp where deptno=10; --(條件過濾查詢)

11、select * from emp where empno > 10; --大於 過濾判斷

12、select * from emp where empno <> 10 --不等於 過濾判斷

13、select * from emp where ename > 'cba'; --字串比較,實際上比較的是每個字元的AscII值,與在Java中字串的比較是一樣的

14、select ename, sal from emp where sal between 800 and 1500; --(between and過濾,包含800 1500)

15、select ename, sal, comm from emp where comm is null; --(選擇comm欄位為null的資料)

16、select ename, sal, comm from emp where comm is not null; --(選擇comm欄位不為null的資料)

17、select ename, sal, comm from emp where sal in (800, 1500,2000); --(in 表範圍)

18、select ename, sal, hiredate from emp where hiredate > '02-2月-1981'; --(只能按照規定的格式寫)

19、select ename, sal from emp where deptno =10 or sal >1000;

20、select ename, sal from emp where deptno =10 and sal >1000;

21、select ename, sal, comm from emp where sal not in (800, 1500,2000); --(可以對in指定的條件進行取反)

22、select ename from emp where ename like '%ALL%'; --(模糊查詢)

23、select ename from emp where ename like '_A%'; --(取第二個字母是A的所有欄位)

24、select ename from emp where ename like '%/%%'; --(用轉義字元/查詢欄位中本身就帶%欄位的)

25、select ename from emp where ename like '%$%%' escape '$'; --(用轉義字元/查詢欄位中本身就帶%欄位的)

26、select * from dept order by deptno desc; (使用order by desc欄位 對資料進行降序排列 預設為升序asc);

27、select * from dept where deptno <>10 order by deptno asc; --(我們可以將過濾以後的資料再進行排序)

28、select ename, sal, deptno from emp order by deptno asc, ename desc; --(按照多個欄位排序 首先按照deptno升序排列,當detpno相同時,內部再按照ename的降序排列)

29、select lower(ename) from emp; --(函式lower() 將ename搜尋出來後全部轉化為小寫);

30、select ename from emp where lower(ename) like '_a%'; --(首先將所搜尋欄位轉化為小寫,然後判斷第二個字母是不是a)

31、select substr(ename, 2, 3) from emp; --(使用函式substr() 將搜素出來的ename欄位從第二個字母開始截,一共截3個字元)

32、select chr(65) from dual; --(函式chr() 將數字轉化為AscII中相對應的字元)

33、select ascii('A') from dual; --(函式ascii()與32中的chr()函式是相反的 將相應的字元轉化為相應的Ascii編碼) )

34、select round(23.232) from dual; --(函式round() 進行四捨五入操作)

35、select round(23.232, 2) from dual; --(四捨五入後保留的小數位數 0 個位 -1 十位)

36、select to_char(sal, '$99,999.9999')from emp; --(加$符號加入千位分隔符,保留四位小數,沒有的補零)

37、select to_char(sal, 'L99,999.9999')from emp; --(L 將貨幣轉化為本地幣種此處將顯示¥人民幣)

38、select to_char(sal, 'L00,000.0000')from emp; --(補零位數不一樣,可到資料庫執行檢視)

39、select to_char(hiredate, 'yyyy-MM-DD HH:MI:SS') from emp; --(改變日期預設的顯示格式)

40、select to_char(sysdate, 'yyyy-MM-DD HH:MI:SS') from dual; --(用12小時制顯示當前的系統時間)

41、select to_char(sysdate, 'yyyy-MM-DD HH24:MI:SS') from dual; --(用24小時制顯示當前的系統時間)

42、select ename, hiredate from emp where hiredate > to_date('1981-2-20 12:24:45','YYYY-MM-DD HH24:MI:SS'); --(函式to-date 查詢公司在所給時間以後入職的人員)

43、select sal from emp where sal > to_number('$1,250.00', '$9,999.99'); --(函式to_number()求出這種薪水裡帶有特殊符號的)

44、select ename, sal*12 + nvl(comm,0) from emp; --(函式nvl() 求出員工的"年薪 + 提成(或獎金)問題")

45、select max(sal) from emp; -- (函式max() 求出emp表中sal欄位的最大值)

46、select min(sal) from emp; -- (函式max() 求出emp表中sal欄位的最小值)

47、select avg(sal) from emp; --(avg()求平均薪水);

48、select to_char(avg(sal), '999999.99') from emp; --(將求出來的平均薪水只保留2位小數)

49、select round(avg(sal), 2) from emp; --(將平均薪水四捨五入到小數點後2位)

50、select sum(sal) from emp; --(求出每個月要支付的總薪水)

------------------------/組函式(共5個):將多個條件組合到一起最後只產生一個數據------min() max() avg() sum() count()----------------------------/

51、select count(*) from emp; --求出表中一共有多少條記錄

52、select count(*) from emp where deptno=10; --再要求一共有多少條記錄的時候,還可以在後面跟上限定條件

53、select count(distinct deptno) from emp; --統計部門編號前提是去掉重複的值

------------------------聚組函式group by() --------------------------------------

54、select deptno, avg(sal) from emp group by deptno; --按照deptno分組,檢視每個部門的平均工資

55、select max(sal) from emp group by deptno, job; --分組的時候,還可以按照多個欄位進行分組,兩個欄位不相同的為一組

56、select ename from emp where sal = (select max(sal) from emp); --求出

57、select deptno, max(sal) from emp group by deptno; --搜素這個部門中薪水最高的的值

--------------------------------------------------having函式對於group by函式的過濾 不能用where--------------------------------------

58、select deptno, avg(sal) from emp group by deptno having avg(sal) >2000; (order by )--求出每個部門的平均值,並且要 > 2000

59、select avg(sal) from emp where sal >1200 group by deptno having avg(sal) >1500 order by avg(sal) desc;--求出sal>1200的平均值按照deptno分組,平均值要>1500最後按照sal的倒序排列

60、select ename,sal from emp where sal > (select avg(sal) from emp); --求那些人的薪水是在平均薪水之上的。

61、select ename, sal from emp join (select max(sal) max_sal ,deptno from emp group by deptno) t on ( = _sal and no=no); --查詢每個部門中工資最高的那個人

------------------------------/等值連線--------------------------------------

62、select e, e from emp e1, emp e2 where = o; --自連線,把一張表當成兩張表來用

63、select ename, dname from emp, dept; --92年語法 兩張表的連線 笛卡爾積。

64、select ename, dname from emp cross join dept; --99年語法 兩張表的連線用cross join

65、select ename, dname from emp, dept where no = no; -- 92年語法 表連線 + 條件連線

66、select ename, dname from emp join dept on(no = no); -- 新語法

67、select ename,dname from emp join dept using(deptno); --與66題的寫法是一樣的,但是不推薦使用using : 假設條件太多

--------------------------------------/非等值連線------------------------------------------/

68、select ename,grade from emp e join salgrade s on( between l and l); --兩張表的連線 此種寫法比用where更清晰

69、select ename, dname, grade from emp e

join dept d on(no = no)

join salgrade s on ( between l and l)

where ename not like '_A%'; --三張表的連線

70、select e, e from emp e1 join emp e2 on( = o); --自連線第二種寫法,同62

71、select e, e from emp e1 left join emp e2 on( = o); --左外連線 把左邊沒有滿足條件的資料也取出來

72、select ename, dname from emp e right join dept d on(no = no); --右外連線

73、select deptno, avg_sal, grade from (select deptno, avg(sal) avg_sal from emp group by deptno) t join salgrade s on (_sal between l and l);--求每個部門平均薪水的等級

74、select ename from emp where empno in (select mgr from emp); -- 在表中搜索那些人是經理

75、select sal from emp where sal not in(select distinct from emp e1 join emp e2 on( < )); -- 面試題 不用組函式max()求薪水的最大值

76、select deptno, max_sal from

(select avg(sal) max_sal,deptno from emp group by deptno)

where max_sal =

(select max(max_sal) from

(select avg(sal) max_sal,deptno from emp group by deptno)

);--求平均薪水最高的部門名稱和編號。

77、select no, grade, avg_sal from

(select deptno, grade, avg_sal from

(select deptno, avg(sal) avg_sal from emp group by deptno) t

join salgrade s on(_sal between l and l)

) t1

join dept on (no = no)

where e =

(

select min(grade) from

(select deptno, grade, avg_sal from

(select deptno, avg(sal) avg_sal from emp group by deptno) t

join salgrade s on(_sal between l and l)

)

)--求平均薪水等級最低的部門的名稱 哈哈 確實比較麻煩

78、create view v$_dept_avg_sal_info as

select deptno, grade, avg_sal from

(select deptno, avg(sal) avg_sal from emp group by deptno) t

join salgrade s on(_sal between l and l);

--檢視的建立,一般以v$開頭,但不是固定的

79、select no, grade, avg_sal from v$_dept_avg_sal_info t1

join dept on (no = no)

where e =

(

select min(grade) from

v$_dept_avg_sal_info t1

)

)--求平均薪水等級最低的部門的名稱 用檢視,能簡單一些,相當於Java中方法的封裝

80、---建立檢視出現許可權不足時候的解決辦法:

conn sys/admin as sysdba;

--顯示:連線成功 Connected

grant create table, create view to scott;

-- 顯示: 授權成功 Grant succeeded

81、-------求比普通員工最高薪水還要高的經理人的名稱 -------

select ename, sal from emp where empno in

(select distinct mgr from emp where mgr is not null)

and sal >

(

select max(sal) from emp where empno not in

(select distinct mgr from emp where mgr is not null)

)

82、---面試題:比較效率

select * from emp where deptno = 10 and ename like '%A%';--好,將過濾力度大的放在前面

select * from emp where ename like '%A%' and deptno = 10;

83、-----表的備份

create table dept2 as select * from dept;

84、-----插入資料

insert into dept2 values(50,'game','beijing');

----只對某個欄位插入資料

insert into dept2(deptno,dname) values(60,'game2');

85、-----將一個表中的資料完全插入另一個表中(表結構必須一樣)

insert into dept2 select * from dept;

86、-----求前五名員工的編號和名稱(使用虛欄位rownum 只能使用 < 或 = 要使用 > 必須使用子查詢)

select empno,ename from emp where rownum <= 5;

86、----求10名僱員以後的僱員名稱--------

select ename from (select rownum r,ename from emp) where r > 10;

87、----求薪水最高的前5個人的薪水和名字---------

select ename, sal from (select ename, sal from emp order by sal desc) where rownum <=5;

88、----求按薪水倒序排列後的第6名到第10名的員工的名字和薪水--------

select ename, sal from

(select ename, sal, rownum r from

(select ename, sal from emp order by sal desc)

)

where r>=6 and r<=10

89、----------------建立新使用者---------------

1、backup scott--備份

exp--匯出

2、create user

create user guohailong identified(認證) by guohailong default tablespace users quota(配額) 10M on users

grant create session(給它登入到伺服器的許可權),create table, create view to guohailong

3、import data

imp

90、-----------事務回退語句--------

rollback;

91、-----------事務確認語句--------

commit;--此時再執行rollback無效

92、--當正常斷開連線的時候例如exit,事務自動提交。 當非正常斷開連線,例如直接關閉dos視窗或關機,事務自動提交

93、/*有3個表S,C,SC

S(SNO,SNAME)代表(學號,姓名)

C(CNO,CNAME,CTEACHER)代表(課號,課名,教師)

SC(SNO,CNO,SCGRADE)代表(學號,課號成績)

問題:

1,找出沒選過“黎明”老師的所有學生姓名。

2,列出2門以上(含2門)不及格學生姓名及平均成績。

3,即學過1號課程有學過2號課所有學生的姓名。

*/答案:

1、

select sname from s join sc on( = ) join c on ( = ) where cteacher <> '黎明';

2、

select sname where sno in (select sno from sc where scgrade < 60 group by sno having count(*) >=2);

3、

select sname from s where sno in (select sno, from sc where cno=1 and cno in

(select distinct sno from sc where cno = 2);

)

94、--------------建立表--------------

create table stu

(

id number(6),

name varchar2(20) constraint stu_name_mm not null,

sex number(1),

age number(3),

sdate date,

grade number(2) default 1,

class number(4),

email varchar2(50) unique

);

95、--------------給name欄位加入 非空 約束,並給約束一個名字,若不取,系統預設取一個-------------

create table stu

(

id number(6),

name varchar2(20) constraint stu_name_mm not null,

sex number(1),

age number(3),

sdate date,

grade number(2) default 1,

class number(4),

email varchar2(50)

);

96、--------------給nameemail欄位加入 唯一 約束 兩個 null值 不為重複-------------

create table stu

(

id number(6),

name varchar2(20) constraint stu_name_mm not null,

sex number(1),

age number(3),

sdate date,

grade number(2) default 1,

class number(4),

email varchar2(50) unique

);

97、--------------兩個欄位的組合不能重複 約束:表級約束-------------

create table stu

(

id number(6),

name varchar2(20) constraint stu_name_mm not null,

sex number(1),

age number(3),

sdate date,

grade number(2) default 1,

class number(4),

email varchar2(50),

constraint stu_name_email_uni unique(email, name)

);

98、--------------主鍵約束-------------

create table stu

(

id number(6),

name varchar2(20) constraint stu_name_mm not null,

sex number(1),

age number(3),

sdate date,

grade number(2) default 1,

class number(4),

email varchar2(50),

constraint stu_id_pk primary key (id),

constraint stu_name_email_uni unique(email, name)

);

99、--------------外來鍵約束 被參考欄位必須是主鍵 -------------

create table stu

(

id number(6),

name varchar2(20) constraint stu_name_mm not null,

sex number(1),

age number(3),

sdate date,

grade number(2) default 1,

class number(4) references class(id),

email varchar2(50),

constraint stu_class_fk foreign key (class) references class(id),

constraint stu_id_pk primary key (id),

constraint stu_name_email_uni unique(email, name)

);

create table class

(

id number(4) primary key,

name varchar2(20) not null

);

100、---------------修改表結構,新增欄位------------------

alter table stu add(addr varchar2(29));

101、---------------刪除欄位--------------------------

alter table stu drop (addr);

102、---------------修改表字段的長度------------------

alter table stu modify (addr varchar2(50));--更改後的長度必須要能容納原先的資料

103、----------------刪除約束條件----------------

alter table stu drop constraint 約束名

104、-----------修改表結構新增約束條件---------------

alter table stu add constraint stu_class_fk foreign key (class) references class (id);

105、---------------資料字典表----------------

desc dictionary;

--資料字典表共有兩個欄位 table_name comments

--table_name主要存放資料字典表的名字

--comments主要是對這張資料字典表的描述

105、---------------檢視當前使用者下面所有的表、檢視、約束-----資料字典表user_tables---

select table_name from user_tables;

select view_name from user_views;

select constraint_name from user-constraints;

106、-------------索引------------------

create index idx_stu_email on stu (email);-- 在stu這張表的email欄位上建立一個索引:idx_stu_email

107、---------- 刪除索引 ------------------

drop index index_stu_email;

108、---------檢視所有的索引----------------

select index_name from user_indexes;

109、---------建立檢視-------------------

create view v$stu as selesct id,name,age from stu;

檢視的作用: 簡化查詢 保護我們的一些私有資料,通過檢視也可以用來更新資料,但是我們一般不這麼用 缺點:要對檢視進行維護

110、-----------建立序列------------

create sequence seq;--建立序列

select val from dual;-- 檢視seq序列的下一個值

drop sequence seq;--刪除序列

111、------------資料庫的三正規化--------------

(1)、要有主鍵,列不可分

(2)、不能存在部分依賴:當有多個欄位聯合起來作為主鍵的時候,不是主鍵的欄位不能部分依賴於主鍵中的某個欄位

(3)、不能存在傳遞依賴

==============================================PL/SQL==========================

112、-------------------在客戶端輸出helloworld-------------------------------

set serveroutput on;--預設是off,設成on是讓Oracle可以在客戶端輸出資料

113、begin

dbms__line('helloworld');

end;

/

114、----------------pl/sql變數的賦值與輸出----

declare

v_name varchar2(20);--宣告變數v_name變數的宣告以v_開頭

begin

v_name := 'myname';

dbms__line(v_name);

end;

/

115、-----------pl/sql對於異常的處理(除數為0)-------------

declare

v_num number := 0;

begin

v_num := 2/v_num;

dbms__line(v_num);

exception

when others then

dbms__line('error');

end;

/

116、----------變數的宣告----------

binary_integer:整數,主要用來計數而不是用來表示欄位型別 比number效率高

number:數字型別

char:定長字串

varchar2:變長字串

date:日期

long:字串,最長2GB

boolean:布林型別,可以取值true,false,null--最好給一初值

117、----------變數的宣告,使用 '%type'屬性

declare

v_empno number(4);

v_empno2 o%type;

v_empno3 v_empno2%type;

begin

dbms__line('Test');

end;

/

--使用%type屬性,可以使變數的宣告根據表字段的型別自動變換,省去了維護的麻煩,而且%type屬性,可以用於變數身上

118、---------------Table變數型別(table表示的是一個數組)-------------------

declare

type type_table_emp_empno is table of o%type index by binary_integer;

v_empnos type_table type_table_empno;

begin

v_empnos(0) := 7345;

v_empnos(-1) :=9999;

dbms__line(v_empnos(-1));

end;

119、-----------------Record變數型別

declare

type type_record_dept is record

(

deptno no%type,

dname e%type,

loc %type

);

begin

v_no:=50;

v_e:='aaaa';

v_:='bj';

dbms__line(v no || ' ' || v e);

end;

120、-----------使用 %rowtype宣告record變數

declare

v_temp dept%rowtype;

begin

v_no:=50;

v_e:='aaaa';

v_:='bj';

dbms__line(v no || '' || v e)

end;

121、--------------sql%count 統計上一條sql語句更新的記錄條數

122、--------------sql語句的運用

declare

v_ename e%type;

v_sal %type;

begin

select ename,sal into v_ename,v_sal from emp where empno = 7369;

dbms__line(v_ename || '' || v_sal);

end;

123、 -------- pl/sql語句的應用

declare

v_emp emp%rowtype;

begin

select * into v_emp from emp where empno=7369;

dbms_output_line(v_e);

end;

124、-------------pl/sql語句的應用

declare

v_deptno no%type := 50;

v_dname e%type :='aaa';

v_loc %type := 'bj';

begin

insert into dept2 values(v_deptno,v_dname,v_loc);

commit;

end;

125、-----------------ddl語言,資料定義語言

begin

execute immediate 'create table T (nnn varchar(30) default ''a'')';

end;

126、------------------if else的運用

declare

v_sal %type;

begin

select sal into v_sal from emp where empno = 7369;

if(v_sal < 2000) then

dbms__line('low');

elsif(v_sal > 2000) then

dbms__line('middle');

else

dbms__line('height');

end if;

end;

127、-------------------迴圈 =====do while

declare

i binary_integer := 1;

begin

loop

dbms__line(i);

i := i + 1;

exit when (i>=11);

end loop;

end;

128、---------------------while

declare

j binary_integer := 1;

begin

while j < 11 loop

dbms__line(j);

j:=j+1;

end loop;

end;

129、---------------------for

begin

for k in 1..10 loop

dbms__line(k);

end loop;

for k in reverse 1..10 loop

dbms__line(k);

end loop;

end;

130、-----------------------異常(1)

declare

v_temp number(4);

begin

select empno into v_temp from emp where empno = 10;

exception

when too_many_rows then

dbms__line('太多記錄了');

when others then

dbms__line('error');

end;

131、-----------------------異常(2)

declare

v_temp number(4);

begin

select empno into v_temp from emp where empno = 2222;

exception

when no_data_found then

dbms__line('太多記錄了');

end;

132、----------------------建立序列

create sequence seq_errorlog_id start with 1 increment by 1;

133、-----------------------錯誤處理(用表記錄:將系統日誌存到資料庫便於以後檢視)

-- 建立日誌表:

create table errorlog

(

id number primary key,

errcode number,

errmsg varchar2(1024),

errdate date

);

declare

v_deptno no%type := 10;

v_errcode number;

v_errmsg varchar2(1024);

begin

delete from dept where deptno = v_deptno;

commit;

exception

when others then

rollback;

v_errcode := SQLCODE;

v_errmsg := SQLERRM;

insert into errorlog values (seq_errorlog_val, v_errcode,v_errmsg, sysdate);

commit;

end;

133---------------------PL/SQL中的重點cursor(遊標)和指標的概念差不多

declare

cursor c is

select * from emp; --此處的語句不會立刻執行,而是當下面的open c的時候,才會真正執行

v_emp c%rowtype;

begin

open c;

fetch c into v_emp;

dbms__line(v_e); --這樣會只輸出一條資料 134將使用迴圈的方法輸出每一條記錄

close c;

end;

134----------------------使用do while 迴圈遍歷遊標中的每一個數據

declare

cursor c is

select * from emp;

v_emp c%rowtype;

begin

open c;

loop

fetch c into v_emp;

(1) exit when (c%notfound); --notfound是oracle中的關鍵字,作用是判斷是否還有下一條資料

(2) dbms__line(v_e); --(1)(2)的順序不能顛倒,最後一條資料,不會出錯,會把最後一條資料,再次的列印一遍

end loop;

close c;

end;

135------------------------while迴圈,遍歷遊標

declare

cursor c is

select * from emp;

v_emp emp%rowtype;

begin

open c;

fetch c into v_emp;

while(c%found) loop

dbms__line(v_e);

fetch c into v_emp;

end loop;

close c;

end;

136--------------------------for 迴圈,遍歷遊標

declare

cursor c is

select * from emp;

begin

for v_emp in c loop

dbms__line(v_e);

end loop;

end;

137---------------------------帶引數的遊標

declare

cursor c(v_deptno no%type, v_job %type)

is

select ename, sal from emp where deptno=v_deptno and job=v_job;

--v_temp c%rowtype;此處不用宣告變數型別

begin

for v_temp in c(30, 'click') loop

dbms__line(v_e);

end loop;

end;

138-----------------------------可更新的遊標

declare

cursor c --有點小錯誤

is

select * from emp2 for update;

-v_temp c%rowtype;

begin

for v_temp in c loop

if(v_ < 2000) then

update emp2 set sal = sal * 2 where current of c;

else if (v_ =5000) then

delete from emp2 where current of c;

end if;

end loop;

commit;

end;

139-----------------------------------procedure儲存過程(帶有名字的程式塊)

create or replace procedure p

is--這兩句除了替代declare,下面的語句全部都一樣

cursor c is

select * from emp2 for update;

begin

for v_emp in c loop

if(v_no = 10) then

update emp2 set sal = sal +10 where current of c;

else if(v_no =20) then

update emp2 set sal = sal + 20 where current of c;

else

update emp2 set sal = sal + 50 where current of c;

end if;

end loop;

commit;

end;

--執行儲存過程的兩種方法:

(1)exec p;(p是儲存過程的名稱)

(2)

begin

p;

end;

/

140-------------------------------帶引數的儲存過程

create or replace procedure p

(v_a in number, v_b number, v_ret out number, v_temp in out number)

is

begin

if(v_a > v_b) then

v_ret := v_a;

else

v_ret := v_b;

end if;

v_temp := v_temp + 1;

end;

141----------------------呼叫140

declare

v_a number := 3;

v_b number := 4;

v_ret number;

v_temp number := 5;

begin

p(v_a, v_b, v_ret, v_temp);

dbms__line(v_ret);

dbms__line(v_temp);

end;

142------------------刪除儲存過程

drop procedure p;

143------------------------建立函式計算個人所得稅

create or replace function sal_tax

(v_sal number)

return number

is

begin

if(v_sal < 2000) then

return 0.10;

elsif(v_sal <2750) then

return 0.15;

else

return 0.20;

end if;

end;

----144-------------------------建立觸發器(trigger) 觸發器不能單獨的存在,必須依附在某一張表上

--建立觸發器的依附表

create table emp2_log

(

ename varchar2(30) ,

eaction varchar2(20),

etime date

);

create or replace trigger trig

after insert or delete or update on emp2 ---for each row 加上此句,每更新一行,觸發一次,不加入則值觸發一次

begin

if inserting then

insert into emp2_log values(USER, 'insert', sysdate);

elsif updating then

insert into emp2_log values(USER, 'update', sysdate);

elsif deleting then

insert into emp2_log values(USER, 'delete', sysdate);

end if;

end;

145-------------------------------通過觸發器更新資料

create or replace trigger trig

after update on dept

for each row

begin

update emp set deptno =:no where deptno =: no;

end;

------只編譯不顯示的解決辦法 set serveroutput on;

145-------------------------------通過建立儲存過程完成遞迴

create or replace procedure p(v_pid %type,v_level binary_integer) is

cursor c is select * from article where pid = v_pid;

v_preStr varchar2(1024) := '';

begin

for i in 0..v_leave loop

v_preStr := v_preStr || '****';

end loop;

for v_article in c loop

dbms__line(v_);

if(v_af = 0) then

p(v_);

end if;

end loop;

end;

146-------------------------------檢視當前使用者下有哪些表---

--首先,用這個使用者登入然後使用語句:

select * from tab;

147-----------------------------用Oracle進行分頁!--------------

--因為Oracle中的隱含欄位rownum不支援'>'所以:

select * from (

select rownum rn, t.* from (

select * from t_user where user_id <> 'root'

) t where rownum <6

) where rn >3

148------------------------Oracle下面的清屏命令----------------

clear screen; 或者 cle scr;

149-----------將建立好的guohailong的這個使用者的密碼改為abc--------------

alter user guohailong identified by abc

--當密碼使用的是數字的時候可能會不行

--使用在10 Oracle以上的正則表示式在dual表查詢

with test1 as(

select 'ao' name from dual union all

select 'yang' from dual union all

select 'feng' from dual )

select distinct regexp_replace(name,'[0-9]','') from test1

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

with tab as (

select 'hong' name from dual union all

select 'qi' name from dual union all

select 'gong' name from dual)

select translate(name,'123456789','') from tab;

CREATE OR REPLACE PROCEDURE

calc(i_birth VARCHAR2) IS

s VARCHAR2(8);

o VARCHAR2(8);

PROCEDURE cc(num VARCHAR2, s OUT VARCHAR2) IS

BEGIN

FOR i

IN REVERSE 2 .. length(num) LOOP

s := s || substr(substr(num, i, 1) + substr(num, i - 1, 1), -1);

END LOOP;

SELECT REVERSE(s) INTO s FROM dual;

END;

BEGIN o := i_birth;

LOOP

cc(o, s);

o := s;

dbms__line(s);

EXIT WHEN length(o) < 2;

END LOOP;

END;

set serveroutput on;

exec calc('19880323');

----算命pl/sql

with t as

(select '19880323' x from dual)

select

case

when mod (i, 2) = 0 then '命好'

when i = 9 then '命運悲慘'

else '一般'

end result

from (select mod(sum((to_number(substr(x, level, 1)) +to_number(substr(x, -level, 1))) *

greatest(((level - 1) * 2 - 1) * 7, 1)),10) i from t connect by level <= 4);

--構造一個表,和emp表的部分欄位相同,但是順序不同

SQL> create table t_emp as

2 select ename,empno,deptno,sal

3 from emp

4 where 1=0

5 /

Table created

--新增資料

SQL> insert into t_emp(ename,empno,deptno,sal)

2 select ename,empno,deptno,sal

3 from emp

4 where sal >= 2500

5 /

select * from tb_product where createdate>=to_date('2011-6-13','yyyy-MM-dd') and createdate<=to_date('2011-6-16','yyyy-MM-dd');

sysdate --獲取當前系統的時間

to_date('','yyyy-mm-dd')

select * from tb_product where to_char(createdate,'yyyy-MM-dd')>='2011-6-13' and to_char(createdate,'yyyy-MM-dd')<='2011-6-16';

select * from tb_product where trunc(createdate)>=? and trunc(createdate)<=?

用trunc函式就可以了

第一次

1、Oracle安裝及基本命令

1.1、Orace簡介

Oracleso一個生產中介軟體和資料庫的較大生產商。其發展依靠了IBM公司。創始人是Larry Ellison。

1.2、Oracle的安裝

1) Oracle的主要版本

Oracle 8;

Oracle 8i;i,指的是Internet

Oracle 9i;相比Oracle8i比較類似

Oracle 10g;g,表示網格技術

所謂網格技術,拿百度搜索為例,現在我們需要搜尋一款叫做“EditPlus”的文字編輯器軟體,當我們在百度搜索框中輸入“EditPlus”進行搜尋時, 會得到百度為我們搜尋到的大量關於它的連結,此時,我們考慮一個問題,如果在我所處的網路環境周邊的某個地方的伺服器就提供這款軟體的下載(也就是說提供一個下載連結供我們下載),那麼,我們就沒必要去訪問一個遠在地球對面的某個角落的伺服器去下載這款軟體。如此一來就可以節省大量的網路資源。使用網格技術就能解決這種問題。我們將整個網路劃分為若干個網格,也就是說每一個使用網路的使用者,均存在於某一個網格,當我們需要搜尋指定資源時,首先在我們所處的網格中查詢是否存在指定資源,沒有的話就擴大搜索範圍,到更大的網格中進行查詢,直到查詢到為止。

2) 安裝Oracle的準備工作

關閉防火牆,以免影響資料庫的正常安裝。

3) 安裝Oralce的注意事項

為了後期的開發和學習,我們將所有資料庫預設賬戶的口令設定為統一口令的,方便管理和使用。

在點選“安裝”後,資料庫相關引數設定完成,其安裝工作正式開始,在完成安裝時,不要急著去點選“確定”按鈕,這時候,我們需要進行一個非常重要的操作——賬戶解鎖。因為在Oracle中預設有一個叫做scott的賬戶,該賬戶中預設有4張表,並且存有相應的資料,所以,為了方便我們學習Oracle資料庫,我們可以充分利用scott這個內建賬戶。但是奇怪的是,在安裝Oracle資料庫的時候,scott預設是鎖住的,所以在使用該賬戶之前,我們就需要對其進行解鎖操作。在安裝完成介面中,點選“口令管理”進入到相應的口令管理介面,找到scott賬戶,將是否解鎖一欄的去掉,即可完成解鎖操作,後期就可以正常使用scott賬戶。我們執行SQLPlus(Oracle提供的命令列操作),會提示我們輸入使用者名稱,現在我們可以輸入使用者名稱scott,回車後,會提示輸入口令,奇怪的是,當我們輸入在安裝時設定的統一口令時,提示登入拒絕,顯然是密碼錯誤,那麼,在Oracle資料庫中,scott的預設密碼是tiger,所以使用tiger可以正常登入,但是提示我們scott的當前密碼已經失效,讓我們重新設定密碼,建議還是設定為tiger。

在Oracle中內建了很多賬戶,那麼,我們來了解下一下幾個比較重要的內建賬戶:

|-普通使用者:scott/tiger

|-普通管理員:system/manager

|-超級管理員:sys/change_on_install

4) 關於Oracle的服務

在Oracle安裝完成之後,會在我們的系統中進行相關服務的註冊,在所有註冊的服務中,我們需要關注一下兩個服務,在實際使用Oracle的過程中,這兩個服務必須啟動才能使Oracle正常使用。

|-第一個是OracleOraDb11g_home1TNSListener,監聽服務,如果客戶端想要連線資料庫,此服務必須開啟。

|-第二個是OracleServiceORCL,資料庫的主服務。命名規則:OracleService + 資料庫名稱,此 服務必須啟動。

此後,我們可以通過命令列方式進入到SQLPlus的控制中心,進行命令的輸入。

1.3、SQLPlus

SQLPlus是Oracle提供的一種命令列執行的工具軟體,安裝之後會自動在系統中進行註冊。連線到資料庫之後,就可以開始對資料庫中的表進行操作了。

1) 對SQLPlus的環境設定

set linesize 長度;--設定每行顯示的長度

set pagesize 行數;--修改每頁顯示記錄的長度。

需要注意的是,上述連個引數的設定只在當前的命令列有效,命令列視窗重啟或者開啟了第二個視窗需要重新設定。

2) SQLPlus常用操作

在SQLPlus中輸入ed ,會彈出找不到檔案的提示框,此時點選“是”,將建立一個檔案,並彈出文字編輯頁面,在這裡可以輸入相關的sql語句,編輯完成後儲存,在命令列中通過 @ 的方式執行命令,如果建立的檔案字尾為“sql”,那麼在執行的時候可以省略掉,即可以這麼寫, @ a。除了建立不存在的檔案外,sqlplus中也可以通過指定本地存在的檔案進行命令的執行,方式為 @ 檔案路徑。

在SQLPlus中可以通過命令使用其他賬戶進行資料庫的連線,如,當前連線的使用者是scott,我們需要使用sys進行連線,則可以這麼操作:conn sys/430583 as sysdba,這裡需要說明的是,sys是超級管理員,當我們需要使用sys進行登入的時候,那麼需要額外的加上as sysdba表示sys將以管理員的身份登入。這裡有幾點可以測試下

|-當我們使用sys以sysdba的角色登入時,其密碼可以隨意輸入,不一定是我們設定的統一口令(430583)。所以,我們得出結論,在管理員登入時,只對使用者進行驗證,而普通使用者登入時,執行使用者和密碼驗證。

在sys賬戶下訪問scott下的emp表時,會提示錯誤,因為在sys中是不存在emp表的,那麼如果需要在sys下訪問scott的表(也就是說需要在a使用者下訪問b使用者下的表),該如何操作呢?首先,我們應該知道每個物件是屬於一種模式(模式是對使用者所建立的資料庫物件的總稱,包括表,檢視,索引,同義詞,序列,過程和程式包等)的,而每個賬戶對應一個模式,所以我們需要在sys下訪問scott的表時,需要指明所訪問的表是屬於哪一個模式的,即,我們可以這樣操作來實現上面的操作:select * from ;

如果我們需要知道當前連線資料庫的賬戶是誰,可以這樣操作:show user;

我們知道,一個數據庫可以儲存多張表,那麼,如何檢視指定資料庫的所有表名稱呢?select * from tab;

在開發過程中,我們需要經常的檢視某張表的表結構,這個操作可以這樣實現:desc emp;

在SQLPlus中,我們可以輸入“/”來快速執行上一條語句。例如,在命令列中我們執行了一條這樣的語句:select * from emp;但是我們需要再次執行該查詢,就可以輸入一個“/”就可快速執行。

3) 常用資料型別

number(4)-->表示數字,長度為4

varchar2(10)-->表示的是字串,只能容納10個長度

date-->表示日期

number(7,2)-->表示數字,小數佔2位,整數佔5位,總共7位

第二次

1、SQL語句

1.1 準備工作--熟悉scott賬戶下的四張表及表結構

第一張表emp-->僱員表,用於儲存僱員資訊

empno number(4) 表示僱員的編號,唯一編號

ename varchar2(10) 表示僱員的姓名

job varchar2(9) 表示工作職位

mgr number(4) 表示一個僱員的上司編號

hiredate date 表示僱傭日期

sal number(7,2) 表示月薪,工資

comm number(7,2) 表示獎金

deptno number(2) 表示部門編號

第二張表dept-->部門表,用於儲存部門資訊

deptno number(2) 部門編號

dname varchar2(14) 部門名稱

loc varchar2(13) 部門位置

第三張表salgrade-->工資等級表,用於儲存工資等級

grade number 等級名稱

losal number 此等級的最低工資

hisal number 此等級的最高工資

第四張表bonus-->獎金錶,用於儲存一個僱員的工資及獎金

ename varchar2(10) 僱員姓名

job varchar2(9) 僱員工作

sal number 僱員工資

comm number 僱員獎金

1.2、SQL簡介

什麼是SQL?

SQL(Structured Query Language,結構查詢語言)是一個功能強大的資料語言。SQL通常用於與資料庫的通訊。SQL是關係資料庫管理系統的標準語言。SQL功能強大,概括起來,分為以下幾組:

|-DML-->Data Manipulation Language,資料操縱語言,用於檢索或者修改資料,即主要是對資料庫表中的資料的操作。

|-DDL-->Data Definition Language,資料定義語言,用於定義資料的結構,如建立、修改或者刪除資料庫物件,即主要是對錶的操作。

|-DCL-->Data Control Language,資料控制語言,用於定義資料庫使用者的許可權,即主要對使用者許可權的操作。

1.3、簡單查詢語句

簡單查詢語句的語法格式是怎樣的?

select * |具體的列名 [as] [別名] from 表名稱;

需要說明的是,在實際開發中,最好不要使用*代替需要查詢的所有列,最好養成顯式書寫需要查詢的列名,方便後期的維護;在給查詢的列名設定別名的時候,可以使用關鍵字as,當然不用也是可以的。

拿emp表為例,我們現在需要查詢出僱員的編號、姓名、工作三個列的資訊的話,就需要在查詢的時候明確指定查詢的列名稱,即

select empno,ename,job from emp;

如果需要指定查詢的返回列的名稱,即給查詢列起別名,我們可以這樣操作

select empno 編號,ename 姓名,job 工作 from emp;--省略as關鍵字的寫法

或者

select empno as 編號,ename as 姓名,job as 做工 from emp; --保留as關鍵字的寫法

如果現在需要我們查詢出emp中所有的job,我們可能這麼操作

select job from emp;

可能加上一個別名會比較好

select job 工作 from emp;

但是現在出現了一個問題,從查詢的結果中可以看出,job的值是有重複的,這是為什麼呢?因為我們知道一個job職位可能會對應多個僱員,比如,在一個公司的市場部會有多名市場人員,在這裡我們使用select job from emp;查詢的實際上是當前每個僱員對應的工作職位,有多少

個僱員,就會對應的查詢出多少個職位出來,所以就出現了重複值,為了消除這樣的重複值,我們在這裡可以使用關鍵字distinct,接下來我們繼續完成上面的操作,即

select distinct job from emp;

所以,我們可以看到,使用distinct的語法是這樣的:

select distinct *|具體的列名 別名 from 表名稱;

但是在消除重複列的時候,需要強調的是,如果我們使用distinct同時查詢多列時,則必須保證查詢的所有列都存在重複資料才能消除掉。也就是說,當我們需要查詢a,b,c三列時,如果a表存在重複值,但是b和c中沒有重複值,當使用distinct時是看不到消除重複列的效果的。拿scott中的emp表為例,我們需要查詢出僱員編號及僱員工作兩個列的值,我們知道一個工作會對應多個僱員,所以,在這種操作中,僱員編號是沒有重複值的,但是工作有重複值,所以,執行此次查詢的結果將是得到每一個僱員對應的工作名稱,顯然,distinct沒起到作用。

現在我們得到了一個新的需求,要求我們按如下的方式進行查詢:

編號是:7369的僱員,姓名是:SMITH,工作是:CLERK

那麼,我們該如何解決呢?在這裡,我們需要使用到Oracle 中的字串連線(“||”)操作來實現。如果需要顯示一些額外資訊的話,我們需要使用單引號將要顯示的資訊包含起來。那麼,上面的操作可以按照下面的方式進行,

select '編號是' || empno || '的僱員,姓名是:' || ename || ',工作是:' || job from emp;

下面我們再看一個新的應用。公司業績很好,所以老闆想加薪,所有員工的工資上調20%,該如何實現呢?難道在表中一個一個的修改工資列的值嗎?很顯然不是的,我們可以通過使用四則運算來完成加薪的操作。

select ename,sal*1.2 newsal from emp;--newsal是為上調後的工資設定的列名

四則運算,+、-、*、/,同樣有優先順序,先乘除後加減。

1.4、限定查詢(where子句)

在前面我們都是將一張表的全部列或者指定列的所有資料查詢出來,現在我們有新的需求了,需要在指定條件下查詢出資料,比如,需要我們查詢出部門號為20的所有僱員、查詢出工資在3000以上的僱員資訊......,這些所謂的查詢限定條件就是通過where來指定的。我們先看看如何通過限定查詢的方式進行相關操作。我們在前面知道了簡單的查詢語法是:

select *|具體的列名 from 表名稱;

那麼,限定查詢的語法格式如下:

select *|具體的列名 from 表名稱 where 條件表示式;

首先,我們現在要查詢出工資在1500(不包括1500)之上的僱員資訊

select * from emp where sal>1500;

下面的操作是查詢出可以得到獎金的僱員資訊(也就是獎金列不為空的記錄)

select * from emp where comm is not null;

很顯然,查詢沒有獎金的操作就是

select * from emp where comm is null;

我們來點複雜的查詢,查詢出工資在1500之上,並且可以拿到獎金的僱員資訊。這裡的限定條件不再是一個了,當所有的限定條件需要同時滿足時,我們採用and關鍵字將多個限定條件進行連線,表示所有的限定條件都需要滿足,所以,該查詢可以這麼進行:

select * from emp where sal>1500 and comm is not null;

現在的需求發生了變化,要求查詢出工資在1500之上,或者可以領取到獎金的僱員資訊。這裡的限定條件也是兩個,但是有所不同的是,我們不需要同時滿足著兩個條件,因為需求中寫的是

“或者”,所以在查詢時,只需要滿足兩個條件中的一個就行。那麼,我們使用關鍵字or來實現“或者”的功能。

select * from emp where sal>1500 or comm is not null;

需求再次發生變化,查詢出工資不大於1500(小於或等於1500),同時不可以領取獎金的僱員資訊,可想這些僱員的工資一定不怎麼高。之前我們使用not關鍵字對限定條件進行了取反,那麼,這裡就相當於對限定條件整體取反。我們分析下,工資不大於1500同時不可以領取獎金的反面含義就是工資大於1500同時可以領取獎金,所以,我們這樣操作:

select * from emp where sal>1500 and comm is not null;

這是原始需求取反後的查詢語句,那麼為了達到最終的查詢效果,我們將限定條件整體取反,即

select * from emp where not(sal>1500 and comm is not null);

在這裡,我們通過括號將一系列限定條件包含起來表示一個整體的限定條件。

我們在數學中學過這樣的表示式:100<a<200,那麼在資料庫中如何實現呢?一樣的,我們現在要查詢出工資在1500之上,但是在3000之下的全部僱員資訊,很顯然,兩個限定條件,同時要滿足才行。

select * from emp where sal>1500 and sal<3000;

這裡不要異想天開的寫成select * from emp where 1500<sal<3000;()試試吧,絕對會報錯。 很簡單,資料庫軟體不支援這樣的寫法,至少現在的資料庫沒有誰去支援這樣的寫法。

在SQL語法中,提供了一種專門指定範圍查詢的過濾語句:between x and y,相當於a>=x and a<=y,也就是包含了等於的功能,其語法格式如下:

select * from emp where sal between 1500 and 3000;

現在我們使用這種範圍查詢的方式修改上面的語句如下:

select * from emp where sal between 1500 and 3000;

好了,我們現在開始使用資料庫中非常重要的一種資料型別,日期型。

查詢出在1981年僱傭的全部僱員資訊,看似很簡單的一個查詢操作,這樣寫嗎?

select * from emp where hiredate=1981;()

很顯然,有錯。hiredate是date型別的,1981看似是一個年份(日期),但是像這樣使用,它僅僅是一個數字而已,型別都匹配,怎麼進行相等判斷呢?繼續考慮。我們先這樣操作,查詢emp表的所有資訊,

select * from emp;

從查詢結果中,我們重點關注hiredate這一列的資料格式是怎麼定義的,

20-2月 -81,很顯然,我們抽象的表示出來是這樣的,

一個月的第幾天-幾月 -年份的後兩位

所以,接下來我們就有思路了,我們就按照這樣的日期格式進行限定條件的設定,該如何設定呢?考慮下,查詢1981年僱傭的僱員,是不是這個意思,從1981年1月1日到1981年12月31日僱傭的就是我們需要的資料呢?所以,這樣操作吧

select * from emp where hiredate between '1-1月 -81' and '31-12月 -81';

可以看到,上面的限定條件使用了單引號包含,我們暫且可以將一個日期看做是一個字串。由上面的範例中我們得到結論: ...除了可以進行數字範圍的查詢,還可以進行日期範圍的查詢。

我們再來看下面的例子,查詢出姓名是smith的僱員資訊,嗯,很簡單,這樣操作

select * from emp where ename='smith';

看似沒有問題,限定條件也給了,單引號也沒有少,可是為什麼查詢不到記錄呢?明明記得emp表中有一個叫做smith的僱員呀?難道被刪掉了,好吧,我們不需要在這裡耗費時間猜測語句自身的問題了,上面的語句在語法上沒有任何問題,我們先看看emp表中有哪些僱員,

select * from emp;

可以看到,確實有一個叫做smith的僱員,但是不是smith,而是SMITH,所以,我們忽略了一個很重要的問題,Oracle是對大小寫敏感的。所以,更改如下:

select * from emp where ename='SMITH';

現在看一個這樣的例子,要求查詢出僱員編號是7369,7499,7521的僱員資訊。如果按照以前的做法,是這樣操作的,

select * from emp where empno=7369 or empno=7499 or empno=7521;

執行一下吧,確實沒任何問題,查詢出指定僱員編號的所有資訊。但是SQL語法提供一種更好的解決方法,使用in關鍵字完成上面的查詢,如下:

select * from emp where empno in(7369,7499,7521);

總結下in的語法如下:

select * from tablename where 列名 in (值1,值2,值3);

select * from tablename where 列名 not in (值1,值2,值3);

需要說明的是,in關鍵字不光可以用在數字上,也可以用在字串的資訊上。看下面的例子

查詢出姓名是SMITH、ALLEN、KING的僱員資訊

select * from emp where ename in('SMITH','ALLEN','KING');

如果在指定的查詢範圍中附加了額外的內容,不會影響查詢結果。

模糊查詢對於提高使用者體驗是非常好的,對於資料庫的模糊查詢,我們通過like關鍵字來實現。首先我們瞭解下like主要使用的兩種萬用字元:

|-“%”-->可以匹配任意長度的內容,包括0個字元;

|-“_”-->可以匹配一個長度的內容。

下面我們看這樣一個需求,查詢所有僱員姓名中第二個字母包含“M”的僱員資訊

select * from emp where ename like '_M%';

說明下,前面的“_”匹配姓名中第一個字母(任意一個字母),“%”匹配M後面出現的0個或者多個字母。

查詢出僱員姓名中包含字母M的僱員資訊。分析可知,字母M可以出現在姓名的任意位置,如何進行正確的匹配呢?

select * from emp where ename like '%M%';

這裡還是使用%,匹配0個或者多個字母,即可以表示M出現在姓名的任意位置上。

如果我們在使用like查詢的時候沒有指定查詢的關鍵字,則表示查詢內容,即

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

相當於我們前面看到的

select * from emp;

前面我們遇到了一個這樣的需求,查詢出在1981年僱傭的所有僱員資訊,當時我們採取的是使用範圍查詢between ... and ...實現的,現在我們使用like同樣可以實現

select * from emp where hiredate like '%81%';

查詢工資中包含6的僱員資訊

select * from emp where sal like '%5%';

在操作條件中還可以使用:>、>=、=、<、<=等計算符號

對於不等於符號,有兩種方式:<>、!=

現在需要我們查詢僱員編號不是7369的僱員資訊

select * from emp where empno<>7369;

select * from emp where empno!=7369;

1.5、對查詢結果進行排序(order by子句)

在查詢的時候,我們常常需要對查詢結果進行一種排序,以方便我們檢視資料,比如以僱員編號排序,以僱員工資排序等。排序的語法是:

select *|具體的列名稱 from 表名稱 where 條件表示式 order by 排序列1,排序列2 asc|desc;

asc表示升序,預設排序方式,desc表示降序。

現在要求所有的僱員資訊按照工資由低到高的順序排列

select * from emp order by sal;

在升級開發中,會遇到多列排序的問題,那麼,此時,會給order by指定多個排序列。要求查詢出10部門的所有僱員資訊,查詢的資訊按照工資由高到低排序,如果工資相等,則按照僱傭日期由早到晚排序。

select * from emp where deptno=10 order by sal desc,hiredate asc;

需要注意的是,排序操作是放在整個SQL語句的最後執行。

1.6、單行函式

在眾多的資料庫系統中,每個資料庫之間唯一不同的最大區別就在於函式的支援上,使用函式可以完成一系列的操作功能。單行函式語法如下:

function_name(column|expression,[arg1,arg2...])

引數說明:

function_name:函式名稱

columne:資料庫表的列名稱

expression:字串或計算表示式

arg1,arg2:在函式中使用引數

單行函式的分類:

字元函式:接收字元輸入並且返回字元或數值

數值函式:接收數值輸入並返回數值

日期函式:對日期型資料進行操作

轉換函式:從一種資料型別轉換到另一種資料型別

通用函式:nvl函式,decode函式

字元函式:

專門處理字元的,例如可以將大寫字元變為小寫,求出字元的長度。

現在我們看一個例子,將小寫字母轉為大寫字母

select upper('smith') from dual;

在實際中,我們會遇到這樣的情況,使用者需要查詢smith僱員的資訊,但是我們資料庫表中存放的是SMITH,這時為了方便使用者的使用我們將使用者輸入的僱員姓名字串轉為大寫,

select * from emp where ename=upper('smith');

同樣,我們也可以使用lower()函式將一個字串變為小寫字母表示,

select lower('HELLO WORLD') from dual;

那麼,將字串的首字母變為大寫該如何實現呢?我們使用initcap()函式來完成上面的操作。

select initcap('HELLO WOLRD') from dual;

在前面的學習中我們知道,在scot賬戶下的emp表中的僱員姓名採用全大寫顯示,現在我們需要激昂姓名的首字母變為大寫,該如何操作呢?

select initcap(ename) from emp;

我們在前面使用了字串連線操作符“||”對字串連線顯示,比如:

select '編號為' || empno || '的姓名是:' || ename from emp;

那麼,在字元函式中提供concat()函式實現連線操作。

select concat('hello','world') from dual;

上面的範例使用函式實現如下:

select concat('編號為',empno,'的姓名是:',ename);?????????

此種方式不如連線符“||”好使。

在字元函式中可以進行字串的擷取、求出字串的長度、進行指定內容的替換

select substr('hello',1,3) 擷取字串,length('hello') 字串長度,replace('hello','l','x') 字串替換 from dual;

通過上面範例的操作,我們需要注意幾以下:

Oralce中substr()函式的擷取點是從0開始還是從1開始;針對這個問題,我們來操作看下,將上面的擷取語句改為:

select substr('hello',0,3) 擷取字串 from dual;

由查詢結果可以發現,結果一樣,也就是說從0和從1的效果是完全一樣,這歸咎於Oracle的智慧化。

如果現在要求顯示所有僱員的姓名及姓名的後三個字元,我們知道,每個僱員姓名的字串長度可能不同,所以我們採取的措施是求出整個字串的長度在減去2,我們這樣操作,

select ename,substr(ename,length(ename)-2) from emp;

雖然功能實現了,但是有沒有羽化的方案呢?當然是有的,我們分析下,當我們在擷取字串的時候,給定一個負數值是什麼效果,對,就是倒著擷取,我們採取這種方式優化如下:

select ename,substr(ename,-3) from emp;

數值函式:

四捨五入:round()

截斷小數位:trunc()

取餘(取模):mod()

執行四捨五入操作,可以指定保留的小數位

select round(789.536) from dual;

select round(789.436) from dual;

select round(789.436,2) from dual;

可以直接對整數進行四捨五入的進位

select round(789.536,-3) from dual;--1000

select round(789.536,-2) from dual;--800

trunc()函式與round()函式的不同在於,trunc不會保留任何的小數位,而且小數點也不會執行四捨五入的操作,也就是說在使用trunc()函式時,它會將數值從小數點截斷,只保留整數部分。

select trunc(789.536) from dual;--789

當然使用trunc()函式也可以設定小數位的保留位數

select trunc(789.536,2) from dual;--789.53

select trunc(789.536,-2) from dual;--700

使用mod()函式可以進行取餘的操作

select mod(10,3) from dual;--1

日期函式:

在Oracle中提供了很多餘日期相關的函式,包括加減日期等。但是在日期進行加或者減結果的時候有一些規律:

日期-數字=日期

日期+數字=日期

日期-日期=數字(天數的差值)

顯示部門10的孤雁進入公司的星期數,要想完成此查詢,必須知道當前的日期,在Oralce中可以通過以下的操作求出當前日期,使用sysdate表示

select sysdate from dual;

如何求出星期數呢?使用公式:當前日期-僱傭日期=天數 / 7 = 星期數,所以

select empno,ename,round((sysdate-hiredate)/7) from emp;

在Oracle中提供了以下的日期函式支援:

months_between()-->求出給定日期範圍的月數

add_months()-->在指定日期上加上指定的月數,求出之後的日期

next_day()-->下一個的今天是哪一個日期

last_day()-->求出給定日期的最後一天日期

查詢出所有僱員的編號,姓名,和入職的月數

select empno,ename,round(months_between(sysdate,hiredate)) from emp;

查詢出當前日期加上4個月後的日期

select add_months(sysdate,4) from dual;

查詢出下一個給定日期數

select next_day(sysdate,'星期一') from dual;

查詢給定日期的最後一天,也就是給定日期的月份的最後一天

select last_day(sysdate) from dual;

轉換函式:

to_char()-->轉換成字串

to_number()-->轉換成數字

to_date()-->轉換成日期

我們先看看前面做的一個範例,查詢所有僱員的僱員編號,姓名和僱傭時間

select empno,ename,hiredate from emp;

但是現在的要求是講年、月、日進行拆分,此時我們就需要使用to_char()函式進行拆分,拆分的時候必須指定拆分的萬用字元:

年-->y,年是四位數字,所以使用yyyy表示

月-->m,月是兩位數字,所以使用mm表示

日-->d,日是兩位數字,所以使用dd表示

select empno,ename,to_char(hiredate,'yyyy') year,to_char(hiredate,'mm') month,to_char(hiredate,'dd') day from emp;

我們還可以使用to_char()進行日期顯示的轉換功能,Oracle中預設的日期格式是:19-4月 -87,而中國喜歡的格式是:1987-04-19

select empno,ename,to_char(hiredate,'yyyy-mm-dd') from emp;

從顯示結果中我們可以看到,對於月份和日的顯示中,如果不足10,就會自動補零,哪個0我們成為前導0,如果不希望顯示前導0的話,則可以使用fm去掉

select empno,ename,to_char(hiredate,'fmyyyy-mm-dd') from emp;

當然,to_char()也可以用在數字上

查詢全部的僱員編號、姓名和工資

select empno,ename,sal from emp;

我們可以看到,當工資數比較大時,是不利於讀的,那麼,我們可以在數字中使用“,”每3位進行一個分隔,此時,就可以使用to_char()進行格式化。格式化時,9並不代表實際的數字9,而是一個佔位符

select empno,ename,to_char(sal,'99,999') from emp;

還有一個問題,工資數表示的是美元還是人民幣呢?如何解決顯示區域的問題呢?我們可以使用下面的兩種符號:

L-->表示Local的縮寫,以本地的語言進行金額的顯示

$-->表示美元

select empno,ename,to_char(sal,'$99,999') from emp;

to_number()是可以講字串變為數字的函式

select to_number('123') + to_number('123') from dual;

to_date()可以講一個字串變為date的資料

select to_date('2012-09-12','yyyy-mm-dd') from dual;

通用函式:

現在又這樣一個需求,求出每個僱員的年薪。我們知道求年薪的話應該加上獎金的,格式為(sal+comm)*12

select empno,ename,(sal+comm)*12 from emp;

檢視結果,可以發現一個很奇怪的顯現,竟然有的僱員年薪為空,這是如何引起的呢?我們分析下,首先可以檢視下所有僱員的獎金列資料,發現只有部分僱員才可以領取獎金,沒有領取獎金

的僱員其comm列是空的,沒有任何值(null),由此,上面的四則運算顯然沒結果。為了解決這個問題,我們需要用到一個通用函式nvl,將一個指定的null值變為指定的內容

select empno,ename,(sal+nvl(comm,0))*12 from emp;

decode()函式,此函式類似於語句

其語法格式為:

decode(col/expression,search1,result1[search2,result2,......][,default])

說明:col/expression-->列名或表示式

ch2......-->為用於比較的條件

result1、result2......-->為返回值

如果col/expression和search i 相比較,相同的話返回result i ,如果沒有與col/expression相匹配的結果,則返回預設值default。

select decode(1,1,'內容是1',2,'內容是2',3,'內容是3') from dual;

那麼,如何在對錶查詢時使用decode()函式呢?我們來定義一個需求,

現在僱員的工作職位有:

CLERK-->業務員

SALESMAN-->銷售人員

MANAGER-->經理

ANALYST-->分析員

PRESIDENT-->總裁

要求我們查詢出僱員的編號,姓名,僱傭日期及工作,將工作替換為上面的中文

select empno 僱員編號,ename 僱員姓名,hiredate 僱傭日期,decode(job,'CLERK','業務員','SALESMAN','銷售人員','MANAGER','經理','ANALYST','分析員','PRESIDENT','總裁') 職位 from emp;