ORACLE學習記錄
以下全屬個人學習oracle的學習記錄,僅供參考,有不對的地方歡迎交流。
我的學習oracle的目錄大致如下:
一:Oracle基礎
1.sql/plus用法詳解
2.基本增刪改查語句
3.列型別與建表語句
4.正確的查詢模型
5.查詢子句詳解
6.約束
7.連線查詢
8.子查詢
9.檢視
二:Oracle進階
1.索引
2.序列
3.同義詞
4.事務
5.函式
6.觸發器
7.pl/sql程式設計
• 匿名塊
• 控制結構
• 過程與函式
• 儲存過程與儲存函式
• 遊標
三:實際操作
1.sql/plus連線伺服器
連線並登陸
sqlplus "使用者名稱/密碼[@主機名 as 身份]"
先連線再登陸
sqlplus/nolog
conn 使用者名稱/密碼[@主機名 as 身份]
退出:
quit
如圖所示:
2.sqlplus做最簡單的查詢
select 3+2 from dual;
注意dual是Oracle中的一個偽表,利用這個偽表可以設定或檢視序列,或者是呼叫一些內建的函式,方便操作。
3.sqlplus的緩衝區
我們輸入的sql命令,會被sqlplus儲存在緩衝區裡,
熟練利用緩衝區,可以提高我們書寫sql的效率
因為緩衝區的內容 可以 修改/刪除,再執行
用list/l 檢視緩衝區內容
4.列型別
5.建表語句
create table 表名 (
列名 列型別,
...
);
create table 表名
as
select 列1,列2...列N from othoretable;
create table 表名
as
select 列1 as 新列1, 列2 as 新列2 ...列N as 新列N
from othertable
6.修改表的語句-add 列
alter table cxb add(
address varchar2(60)
);
7.修改表的語句-drop列
作用:刪除表中的列
語法: alter table 表名 drop column 列名
關於刪除列的注意事項:
原則上,列都可以刪
但,如果一個列作為主鍵出現
或者作為另1張表的外來鍵,則不能刪除
8.修改表的語句-modify 列
作用:修改表中的列
語法: alter table 表名 modify (
列1 新資料型別 [非空屬性]
..
);
關於修改列的注意事項:
如果表中沒有資料,則列的長度可增加或減小
如果已有資料,則只能增大,不能減小.
9.修改表的語句-修改列名
作用:修改表中的列名
語法: alter table 表名 rename column 舊列名 to 新列
10.關於表的其他DDL語句
刪除表: drop table 表名
改表名: rename table 舊名 to 新名
清空表: truncate table 表名
truncate清空表資料,且不可恢復,慎重.
11.約束
約束概念:
約束是加在表上的一種強制性的規則 ,是保證資料完整性的一種重要手段 .
當向表中插入或修改資料時,必須滿足約束所規定的條件.
如性別必須是"男/女",部門號必須是已存在的部門號等等.
一般而言,保證資料完整性大致有3種方法
程式程式碼,觸發器,約束.
約束型別:
NOT NULL 非空約束
UNIQUE 唯一性約束
PRIMARY KEY 主鍵約束
FOREIGN KEY 外來鍵約束
CHECK 檢查約束
11.1:約束的建立(1)
建表時建立約束
create table 表名 (
列1 資料型別 constraint 約束名1 約束型別,
列2 資料型別 constraint 約束名2 約束型別,
...
);
11.2:約束的建立(2)
11.3:外來鍵的宣告
外來鍵的宣告稍複雜一點,因為牽涉到另一張表
create table 表名 (
列1 列型別
contraint 約束名 foreign key (列名) references 其他表(列名)
注意: 另一張表被引用的列需是主鍵或Unique
11.4:建表後新增約束
在需要批量匯入資料時,約束會影響匯入速度,
可以先不要約束,匯入完畢後,再新增約束.
alter table 表名 add (
constraint 約束名 約束型別(列名),
constraint 約束名 約束型別(列名)
);
alter table 表名 modify (
列名 constraint 約束名 not null
) ; // 因為not null 型別必須宣告在列上,無法宣告在表上,所以必須用modify方式來寫
11.5:約束的刪除與禁用
想改一個約束型別,只能先刪除約束再新增新的約束
語法:
alter table 表名 drop constraint 約束名;
如 alter table student drop constraint gen_check
注意:如果刪除主鍵約束時,該主鍵是另一表的外來鍵,則該主鍵不能直接刪除.
除非連帶把外來鍵約束也刪除.
如 alter table dept drop constraint pk_dept cascade;
也可以臨時禁用1個約束
alter table 表名 disable consstaint 約束名
注意:如果禁用約束後加了一些非法資料,再開啟約束是會失敗的
12.序列 sequence
序列是一種資料庫物件,用來自動生成一組唯一的序號.
序列是一種共享式的物件,多個使用者可以共同使用序列中的序號.
一般將序列應用於表的主鍵列,這樣,當向表中插入資料時,主鍵列就使用了序列的序號,從而保證主鍵不會重複.
用序列來產生主鍵,可以獲得可靠的主鍵值.
一句話: 序列就是序號生成器!
12.1:序列 sequence 的建立
create sequence 序列名 increment by n
start with n
maxvalue n | nomaxvalue
minvalue n | nominvalue
cycle | nocycle
cache n | nocache
上圖建立了名稱為mm的序列,每次增長1,從1開始,沒有最大值,沒有最小值,不迴圈,系統先快取20個序列。
12.2:序列 sequence 的使用
序列的作用就是為我們提供序號,
序列提供了2個偽列, nextval, currval
很明顯,分別是"下個值", "當前值"
select seq1.nextval from dual;
insert into xx表(col1,col2) values (seq1.nextavl,yy);
12.3:序列 sequence 的修改和刪除
alter sequence 序列名
選項 新值
如
alter sqquence 序列名
maxvalue 5
注意:
1:不能修改開始值
2:修改隻影響新產生的值,不影響已產生的值
drop sequence 序列名
13.同義詞
同義詞就是別名,外號
create [public] synonym 同義詞 for 使用者名稱.物件名
drop synonym 同義詞
public 是所有使用者可用的同義詞,一般由DBA建立
注:scott使用者預設沒有建立synonym的許可權
需要授權:
grant create synonym to scott
14.增刪改查
14.1:select 子句介紹
Where 條件查詢
group by 分組
having 篩選
order by 排序
14.2:select 子句 之group與統計函式
max : 求最大
min : 求最小
sum : 求總和
avg : 求平均
count:求總行數
14.3:select 子句 之group介紹
group by
作用:把行 按 欄位 分組
語法:group by col1,col2,...colN
運用場合
常見於統計場合,如按欄目計算帖子數,
統計每個人的平均成績等.
14.4:select 子句 之having介紹
14.5:子查詢
子查詢就是在原有的查詢語句中,
嵌入新的查詢,來得到我們想要的結果集。
一般根據子查詢的嵌入位置分為,
where型子查詢,from型子查詢
14.5.1:where型子查詢
where型子查詢即是:把內層sql語句查詢的結果作為外層sql查詢的條件
典型語法:
select * from tableName
where colName = (select colName from tbName where ....)
{where colName in (select colName from tbName where ..)}
14.5.2:exists型子查詢
exists即:外層sql查詢所查到的行代入內層sql查詢,要使內層查詢能夠成立
查詢可以與in型子查詢互換,但效率要高.
典型語法:
select * from tablename
where exists(select * from tableName where ...)
14.5.3:from型子查詢
from型子查詢即:把內層sql語句查詢的結果作為臨時表供外層sql語句再次查詢.
典型語法:
select * from (select * from tableName where ...) where....
15.連線查詢 之連線查詢語法
左連線的語法.
Select Ltable.* ,Rtable.* from
Ltable left join Rltable
on Ltable.colName = Rtable.colName
典型的例子:學生表,科目表,學生選科目id學習,查詢學生的時候聯查科目表,學生表裡存的有科目表的id,查詢出學生資訊帶科目的資訊。如圖:
內連線的語法.
Select Ltable.* ,Rtable.* from
Ltable inner join Rltable
on Ltable.colName = Rtable.colName
16.檢視 view
檢視是一種虛擬表,本身不儲存資料,而是從表中取得的資料。
可以理解為表的對映,或更簡單的理解為一個查詢結果。
比如,我們頻繁的查詢如下語句:
select empno,ename,sal from emp where sal > (select avg(sal) from emp);
如果把這個語句定義為檢視,並從檢視查詢資料
16.1:檢視 view的用途
1:檢視可以幫我們簡化查詢
如上頁中的複雜查詢,如果不用檢視,則需要子查詢才能達到效果
2:檢視可以幫我更精細的控制權限
比如一張表,有工資列,密碼列,等,
我們可以選擇列生成檢視,開放給不同的使用者,
達到列級的許可權控制
16.2:檢視 view的操作語法
建立檢視:
Create or replace view 檢視名
As select 語句
With read only --是否只讀
With check option –是否執行約束檢查
刪除檢視:
Drop view 檢視名
16.3:複雜檢視
如果select 語句中只針對單表進行列的查詢,且沒有對列進行表示式運算或函式運算,
這種稱為簡單檢視。
如果對多個表進行查詢,或列經過運算,或分組等,這種稱為複雜檢視。
複雜檢視不能進行DML操作
本質區別:數學上是否一一對應。
即任意一行檢視的記錄,能對應表中唯一的一行,就是簡單檢視
17.索引 index
索引就像字典前的“按拼音/偏旁查詢目錄”,
可以提高查詢效率,降低了增刪改的效率。
*資料庫內部常用雜湊索引,和btree索引
17.1:索引 index 的建立與查詢
create [unique] index 索引名
on 表名(列1,列2...)
建1個列上稱為單列索引
否則稱複合索引
索引資訊存放在 user_indexes ,user_ind_columns表
刪除索引
Drop index 索引名
17.2:索引 index 的注意事項
在where子句中經常使用的列上建立索引
大量重複的值加索引意義不大
具有唯一值的列是建索引的好的選擇,但具體還要看是否經常用他查詢。
如果where經常用某N個列一些查詢,考慮建複合索引
索引是有代價的--降低了增刪改的速度,並不是加的越多越好。
18.事務
原子性(Atomicity):原子意為最小的粒子,或者說不能再分的事物。
資料庫事務的不可再分的原則即為原子性。
組成事務的所有查詢必須:
要麼全部執行,要麼全部取消(就像上面的銀行例子)。
一致性(Consistency):指資料的規則,在事務前/後應保持一致
隔離性(Isolation):簡單點說,某個事務的操作對其他事務不可見的.
永續性(Durability):當事務完成後,其影響應該保留下來,不能撤消
18.1:事務 之事務的用法
開啟事務(第1條dml語句即進入事務)
執行sql操作(普通sql操作)
設定儲存點(savepoint 儲存點)
提交/回滾(commit/rollback)
部分回滾(rollback to 儲存點)
18.2:事務的隱式提交
事務可以顯式的提交,也可以隱式的提交
顯式:commit
隱式: 遇到DDL或DCL語句,或退出系統時
會隱式提交
四:PL/sql程式設計
1.PL/sql概念
Procedural language
sql是一種標準的資料庫訪問語言,但無法程式設計,
PL/SQL是Oracle公司開發的“方言”,允許程式設計,
是對SQL的一種補充。
2.PL/sql的結構
declare
變數宣告部分
begin
執行部分
exception
異常處理部分
End
*:declare 和 exception部分是可選的
預設:呼叫一個匿名塊/儲存過程後,只執行不輸出
學習除錯時: set serveroutput on
3.PL/sql中變數的定義
變數 的定義有2種格式
變數名 變數型別 [約束] default 預設值
變數名 變數型別 [約束] [:=初始值]
-------
變數名 表名%rowtype
變數名 表名.列%type
變數名 另一變數%type
4.PL/sql塊中流程控制
5.PL/sql訪問資料庫
PL/SQL的主要目的是對資料庫進行操作,
因此,在PL/SQL塊中可以包含select語句,DML語句,
還可以包含DCL語句.
但不能包含DDL語句.
通過SQL語句及流程控制,可以編寫複雜的PL/SQL塊,
對資料庫進行復雜的訪問.
注意,PL/SQL一般是在應用程式中呼叫.
6.附錄:PL/sql預定義異常
NO_DATA_FOUND 在使用SELECT INTO 結構,並且語句返回NULL值的時候;訪問巢狀表中已經刪除的表或者是訪問INDEX BY表(聯合陣列)中的未初始化元素就會出現該異常
TOO_MANY_ROWS 常見錯誤,在使用SELECT INTO 並且查詢返回多個行時引發。如果子查詢返回多行,而比較運算子為相等的時候也會引發該異常。
ZERO_DIVIDE 將某個數字除以0的時候,會發生該異常
ACCESS_INTO_NULL 試圖訪問未初始化物件的時候出現
CASE_NOT_FOUND 如果定義了一個沒有ELSE子句的CASE語句,而且沒有CASE語句滿足執行時條件時出現該異常
COLLECTION_IS_NULL 當程式去訪問一個沒有進行初始化的NESTED TABLE或者是VARRAY的時候,會出現該異常
CURSOR_ALREADY_OPEN 遊標已經被OPEN,如果再次嘗試開啟該遊標的時候,會出現該異常
DUP_VAL_ON_INDEX 如果插入一列被唯一索引約束的重複值的時候,就會引發該異常(該值被INDEX認定為衝突的)
INVALID_CURSOR 不允許的遊標操作,比如關閉一個已經被關閉的遊標,就會引發
INVALID_NUMBER 給數字值賦非數字值的時候,該異常就會發生,這個異常也會發生在批讀取時候LIMIT子句返回非正數的時候
LOGIN_DENIED 程式中,使用錯誤的使用者名稱和密碼登入的時候,就會丟擲這個異常
NOT_LOGGED_ON 當程式發出資料庫呼叫,但是沒有連線的時候(通常,在實際與會話斷開連線之後)
PROGRAM_ERROR 當Oracle還未正式捕獲的錯誤發生時常會發生,這是因為資料庫大量的Object功能而發生
ROWTYPE_MISMATCH 如果遊標結構不適合PL/SQL遊標變數或者是實際的遊標引數不同於遊標形參的時候發生該異常
SELF_IS_NULL 呼叫一個物件型別非靜態成員方法(其中沒有初始化物件型別例項)的時候發生該異常
STORAGE_ERROR 當記憶體不夠分配SGA的足夠配額或者是被破壞的時候,引發該異常
SUBSCRIPT_BEYOND_COUNT 當分配給NESTED TABLE或者VARRAY的空間小於使用的下標的時候,發生該異常(類似於java的ArrayIndexOutOfBoundsException)
SUBSCRIPT_OUTSIDE_LIMIT 使用非法的索引值來訪問NESTED TABLE或者VARRAY的時候引發
SYS_INVALID_ROWID 將無效的字串轉化為ROWID的時候引發
TIMEOUT_ON_RESOURCE 當資料庫不能安全鎖定資源的時候引發
USERENV_COMMITSCN_ERROR 只可使用函式USERENV('COMMITSCN')作為INSERT語句的VALUES子句中的頂級表示式或者作為UPDATE語句的SET子句中的右運算元
VALUE_ERROR 將一個變數賦給另一個不能容納該變數的變數時引發
7.儲存過程與儲存函式
前面用到的過程和函式都是寫在PL/SQL塊中,
放在緩衝區裡.沒有進行儲存,
下次要使用了再次宣告,呼叫.
我們可以把過程和函式建立並儲存在資料庫中,形成一個物件.
這種儲存後的過程和函式,稱為:
儲存過程 儲存函式
7.1:儲存過程與儲存函式建立語法
create or replace procedure 名稱[(引數)]
authid current_user|definer --以定義者還是呼叫者的身份執行
is[不要加declare]
變數宣告部分
begin
主體部分
exception
異常部分
end;
7.2:儲存過程與儲存函式的刪除
drop procedure 儲存過程名
drop function 函式名
8.遊標-cursor
遊標是一種私有的工作區,用於儲存sql語句的執行結果.
在執行一條sql語句時,資料庫服務區工作區,
這裡儲存了sql語句執行的相關資訊
工作區有2種形式的遊標,隱式的和顯式的.
隱式遊標由資料庫自動定義,顯示遊標由使用者自己定義.
遊標-cursor 簡單例子:
begin
delete from student where sid=9;
if SQL%ROWCOUNT>0 then
dbms_output.put_line('影響了');
else
dbms_output.put_line('沒影響');
end if;
end;
9.觸發器
個人粗暴的解釋,就是當某個動作發生之後或者之前觸發執行。
9.1:觸發器建立語法
u建立觸發器的語法
create trigger 觸發器名稱
after/before/instead of(觸發時間)
insert/update/delete [of列名] (監視事件)
on 表名 (監視地址)
[for each row [when條件]]
begin
sql1;
..
sqlN;
end
9.2:觸發器的刪除
drop trigger triggerName
10.建立使用者與刪除使用者
create user 使用者名稱 identified by “密碼"
default tablespace users
temporary tablespace temp
quota 20M on users
password expire
account unlock;
drop user 使用者名稱
如果使用者名稱已經有表,檢視等,則不允許刪除。
11.修改使用者密碼
後續附上個人練習一些片段,瞌睡來兮了,偷個懶,很多都是截圖了,嘻嘻。。。。。。
Microsoft Windows [版本 10.0.17134.165]
(c) 2018 Microsoft Corporation。保留所有權利。
C:\Users\81046>sqlplus
SQL*Plus: Release 11.2.0.1.0 Production on Thu Aug 16 13:53:36 2018
Copyright (c) 1982, 2010, Oracle. All rights reserved.
Enter user-name:
ERROR:
ORA-01017: invalid username/password; logon denied
Enter user-name: sys
Enter password:
ERROR:
ORA-28009: connection as SYS should be as SYSDBA or SYSOPER
Enter user-name: system
Enter password:
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> select 3
2 select 3 from dual;
select 3 from dual
*
ERROR at line 2:
ORA-00923: FROM keyword not found where expected
SQL> select 3 from dual;
3
----------
3
SQL> create table student(
2 sid number not null,
3 sname char(10)
4 );
Table created.
SQL> insert into student values (1,'wangwu');
1 row created.
SQL> select * from student;
SID SNAME
---------- ------------------------------
1 wangwu
SQL> alert table student add(
SP2-0734: unknown command beginning "alert tabl..." - rest of line ignored.
SQL> alter table student add(
2 area varchar2(20),
3 age number(3,1),
4 height number(3,2)
5 );
Table altered.
SQL> desc student;
Name Null? Type
----------------------------------------- -------- ----------------------------
SID NOT NULL NUMBER
SNAME CHAR(10)
AREA VARCHAR2(20)
AGE NUMBER(3,1)
HEIGHT NUMBER(3,2)
SQL> alter table drop column height;
alter table drop column height
*
ERROR at line 1:
ORA-00903: invalid table name
SQL> alter table student drop column height;
Table altered.
SQL> alter table student modify age number(5,0);
Table altered.
SQL> des
declare
i int :=9;
begin
i:=i*2;
dbms_output.put_line('now i is:'||i);
end;
/
declare
age number default 90;
height number := 175;
gender char(2) := 'mile';
begin
if gender='mile' then
dbms_output.put_line('you can mary with femile');
end if;
if height>170 then
dbms_output.put_line('can play basketebool');
else
dbms_output.put_line('can play footbool');
end if;
if age<20 then
dbms_output.put_line('younth');
elsif age <= 50 then
dbms_output.put_line('seccuss');
elsif age <=70 then
dbms_output.put_line('happniess');
else
dbms_output.put_line('subject');
end if;
end;
儲存過程一個沒有返回值的函式
create or replace procedure p1(dpnum number) is
cnt number;
sals number;
begin
select count(*),sum(sal) into cnt,sals from emp where deptno=dpnum;
dbms_output.put_line('has '||cnt||'worker,sals is'||sals);
end;
/
create or replace procedure p1(dpnum number) is
cnt number;
sals number;
dn varchar2(14);
dl varchar2(13);
begin
select dname,loc into dn,dl from dept where deptno=dpnum;
select count(*),sum(sal) into cnt,sals from emp where deptno=dpnum;
dbms_output.put_line('localtion:'||dl||'company:'||dn||'has '||cnt||'worker,sals is'||sals);
end;
/
create or replace procedure p1(dpnum number) is
cnt number;
sals number;
dn varchar2(14);
dl varchar2(13);
begin
select dname,loc into dn,dl from dept where deptno=dpnum;
select count(*),sum(sal) into cnt,sals from emp where deptno=dpnum;
dbms_output.put_line('localtion:'||dl||' company:'||dn||'has '||cnt||'worker,sals is'||sals);
end;
/
create or replace procedure p12(dpnum int) is
type dpinfo is record
(
dname varchar2(14),
loc varchar2(13),
cnt int,
sal number
);
dp dpinfo;
begin
select dname,loc into dp.dname,dp.loc from dept where deptno=dpnum;
select count(*),sum(sal) into dp.cnt,dp.sal from emp where deptno=dpnum;
dbms_output.put_line(dp.dname||'--'||dp.loc||'--'||dp.cnt||'--'||dp.sal);
end;
/
create or replace procedure p12(dpnum int) is
type dpinfo is record
(
dname varchar2(14),
loc varchar2(13),
cnt int,
sal number,
);
dp dpinfo;
begin
select dname, loc into dp.dname, dp.loc from dept where deptno=dpnum;
select count(*), sum(sal) into dp.cnt, dp.sal from emp where deptno=dpnum;
dbms_output.put_line(dp.dname||'--'||dp.loc||'--'||dp.cnt||'--'||dp.sal);
end;
/
create or replace procedure p12(dpnum int) is
type dpinfo is record
(
dname varchar2(14),
loc varchar2(13),
cnt int,
sal number,
);
dp dpinfo;
begin
select dname, loc into dp.dname, dp.loc from dept where deptno=dpnum;
select count(*), sum(sal) into dp.cnt, dp.sal from emp where deptno=dpnum;
dbms_output.put_line(dp.dname||'__'||dp.loc||'__'||dp.cnt||'__'||dp.sal);
end;
/
create or replace procedure p13(dpnum int) is
dp dept%rowtype;
dn dept.dname%type;
begin
select deptno,dname,loc into dp.deptno,dn,dp.loc from dept
where deptno=dpnum;
dbms_output.put_line(dp.deptno||'__'||dn||'__'||dp.loc);
exception
when NO_DATA_FOUND then
dbms_output.put_line('sorry NO_DATA_FOUND');
end;
/
以上是表級觸發器
監聽到表裡的資料有更改則觸發
create trigger tg1
after insert
on o
begin
dbms_output.put_line('has somone pay goods');
end;
/
create or replace trigger tg2
after insert
on o for each row
begin
update g set cnt=cnt-:new.much where gid=:new.gid;
end;
/
create or replace trigger tg2
after insert
on o for each row
begin
update g set cnt=cnt-:new.much where gid=:new.gid;
dbms_output.put_line('update number');
end;
/
create or replace trigger tg3
before insert on o
for each row
declare
curr number;
begin
select cnt into curr from g where gid=:new.gid;
if curr<:new.much then
:new.much :=curr;
end if;
update g set cnt=cnt-:new.much where gid=:new.gid;
end;
/
create or replace trigger tg3
before insert on o
for each row
declare
curr number;
begin
select cnt into curr from g where gid=:new.gid;
if curr<:new.much then
:new.much :=curr;
end if;
update g set cnt=cnt-:new.much where gid=:new.gid;
end;
/
Microsoft Windows [版本 10.0.17134.228]
(c) 2018 Microsoft Corporation。保留所有權利。
C:\Users\81046>sqlplus sys/root123456 as sysdba;
SQL*Plus: Release 11.2.0.1.0 Production on Fri Aug 17 09:00:03 2018
Copyright (c) 1982, 2010, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> conn scott/tiger;
Connected.
SQL> show user
USER is "SCOTT"
SQL> select seq1.nextval from dual;
NEXTVAL
----------
21
SQL> create view newgoods as select * from goods where doods_id>1;
create view newgoods as select * from goods where doods_id>1
*
ERROR at line 1:
ORA-00904: "DOODS_ID": invalid identifier
SQL> select * from goods;
GOODS_ID CAT_ID
---------- ----------
GOODS_NAME
--------------------------------------------------------------------------------
1 8
nokia
7 8
fengtian
8 8
food8
GOODS_ID CAT_ID
---------- ----------
GOODS_NAME
--------------------------------------------------------------------------------
9 5
book9
&nbs