|
一、SQLPLUS 1引言
SQL命令 以下17個是作為語句開頭的關鍵字: alterdroprevoke auditgrantrollback* commit*insertselect commentlockupdate createnoauditvalidate deleterename 這些命令必須以“;”結尾 帶*命令句尾不必加分號,并且不存入SQL緩存區。
SQL中沒有的SQL*PLUS命令 這些命令不存入SQL緩存區 @definepause #delquit $describeremark /disconnectrun acceptdocumentsave appendeditset breakexitshow btitlegetspool changehelpsqlplus clearhoststart columninputtiming computelistttitle connectnewpageundefine copy
--------- 2數據庫查詢
數據字典 TAB用戶創建的所有基表、視圖和同義詞清單
DTAB構成數據字典的所有表
COL用戶創建的基表的所有列定義的清單
CATALOG用戶可存取的所有基表清單
select*fromtab;
describe命令描述基表的結構信息 describedept
select* fromemp;
selectempno,ename,job fromemp;
select*fromdept orderbydeptnodesc;
邏輯運算符 =!=或<>>>=<<= in betweenvalue1andvalue2 like % _ innull not noin,isnotnull
謂詞in和notin 有哪些職員和分析員 selectename,job fromemp wherejobin('clerk','analyst');
selectename,job fromemp wherejobnotin('clerk','analyst');
謂詞between和notbetween 哪些雇員的工資在2000和3000之間 selectename,job,salfromemp wheresalbetween2000and3000;
selectename,job,salfromemp wheresalnotbetween2000and3000;
謂詞like,notlike selectename,deptnofromemp whereenamelike'S%'; (以字母S開頭) selectename,deptnofromemp whereenamelike'%K'; (以K結尾) selectename,deptnofromemp whereenamelike'W___'; (以W開頭,后面僅有三個字母) selectename,jobfromemp wherejobnotlike'sales%'; (哪些雇員的工種名不以sales開頭)
謂詞isnull,isnotnull 沒有獎金的雇員(即commision為null) selectename,jobfromemp wherecommisnull;
selectename,jobfromemp wherecommisnotnull;
多條件查詢 selectename,job fromemp wheredeptno=20 andjob!='clerk';
表達式 +-*/
算術表達式 選擇獎金高于其工資的5%的雇員 selectename,sal,comm,comm/salfromemp wherecomm>.05*sal orderbycomm/saldesc;
日期型數據的運算 addtwodaysto6-Mar-87 6-Mar-87+2=8-Mar-87 addtwohoursto6-Mar-87 6-Mar-87+2/24=6-Mar-87and2hrs add15secondsto6-Mar-87 6-Mar-87+15/(24*60*60)=6-Mar-87and15secs
列名的別名 selectenameemployeefromemp wheredeptno=10; (別名:employee) selectename,sal,comm,comm/sal"C/SRATIO"fromemp wherecomm>.05*sal orderbycomm/saldesc;
SQL命令的編輯 listorl顯示緩沖區的內容 list4顯示當前SQL命令的第4行,并把第4行作為當前行,在該行號后面有個*。 changeorc用新的內容替換原來在一行中第一次出現內容 SQL>c/(...)/('analyst')/ inputori增加一行或多行 appendora在一行后追加內容 del刪除當前行刪除SQL緩沖區中的當前行 run顯示并運行SQL緩沖區中的命令 /運行SQL緩沖區中的命令 edit把SQL緩沖區中的命令寫到操作系統下的文本文件, 并調用操作系統提供的編輯器執行修改。
------------- 3數據操縱 數據的插入 insertintodept values(10,'accounting','newyork');
insertintodept(dname,deptno) values('accounting',10);
從其它表中選擇插入數據 insertintoemp(empno,ename,deptno) selectid,name,department fromold_emp wheredepartmentin(10,20,30,40);
使用參數 insertintodept values(&deptno,&dname,&loc); 執行時,SQL/PLUS對每個參數將有提示用戶輸入
參數對應日期型或字符型數據時,可在參數上加引號,輸入時就可不用引號 insertintodept values(&deptno,'&dname','&loc');
插入空值(NULL) insertintodept values(50,'education',null);
插入日期型數據 日期型數據缺省格式:DD-MON-YY insertintoemp (empno,ename,hiredate) values(7963,'stone','07-APR-87');
系統時間:SYSDATE insertintoemp (empno,ename,hiredate) values(7600,'kohn',SYSDATE);
數據更新 updateemp setjob='manager' whereename='martin';
updateemp setjob='marketrep' whereename='salesman';
updateemp setdeptno=40,job='marketrep' wherejob='salesman';
數據刪除 deleteemp whereempno=765;
更新的提交 commit
自動提交方式 setautocommiton 如果狀態設為開,則使用inesrt,update,delete會立即提交。
更新取消 rollback
兩次連續成功的commit之間的操作,稱為一個事務
--------------- 4創建基表、視圖 創建基表 createtabledept (deptnonumber(2), dnamechar(14), locchar(13));
數據字典會自動更新。 一個基表最多254列。
表名列名命名規則: 限制 第一個字符必須是字母,后面可任意(包括$#_但不能是逗號)。 名字不得超過30個字符。
唯一 某一用戶的基表名必須唯一,不能是ORACLE的保留字,同一基表的列名互不相同。
使用雙引號 如果表名用雙引號括起來,則可不滿足上述規則; 只有使用雙引號,才能區別大、小寫; 命名時使用了雙引號,在以后的操作也必須使用雙引號。
數據類型: char(n)(不得超過240字符) number(n,d) date long(最多65536字符) raw(二進制原始數據)
空值處理 有時要求列值不能為空 createtabledept (deptnonumber(2)notnull, dnamechar(14), locchar(13));
在基表中增加一列 altertabledept add(headcntnumber(3));
修改已有列屬性 altertabledept modifydnamechar(20); 注:只有當某列所有值都為空時,才能減小其列值寬度。 只有當某列所有值都為空時,才能改變其列值類型。 只有當某列所有值都為不空時,才能定義該列為notnull。 例: altertabledeptmodify(locchar(12)); altertabledeptmodifylocchar(12); altertabledeptmodify(dnamechar(13),locchar(12));
創建視圖 createviewmanagersas selectename,job,sal fromemp wherejob='manager';
為視圖列名取別名 createviewmydept (person,title,salary) asselectename,job,sal fromemp wheredeptno=10;
withcheckoption選項 使用withcheckoption,保證當對視圖插入或更新數據時, 該數據必須滿足視圖定義中select命令所指定的條件。 createviewdept20as selectename,job,sal,deptno fromemp wheredeptno=20 withcheckoption; 在做下述操作時,會發生錯誤 updatedept20 setdeptno=30 whereename='ward';
基表、視圖的拷貝 createtableemp2 asselect*fromemp;
基表、視圖的刪除 droptable表名 dropview視圖名
------------ 5SQL*PLUS報表功能 SQL*PLUS的一些基本格式命令 columndeptnoheadingdepartment
columnenameheadingname
columnsalheadingsalary
columnsalformat$99,999.00
ttitlesamplereportfor|hitechcorp
btitlestrictlyconfidential
breakondeptno
computesumofsalondeptno
run
表頭和表尾 ttitlesamplereportfor|hitechcorp btitlerightstrictlyconfidential
“|”表示換行,結尾不必加分號 選項有三種:leftrightcenter
使用TTITLE,系統將自動地在每頁的頂部顯示日期和頁號。 TTITLET和BTITLE命令有效,直至重新設置表頭或表尾,或退出SQL*PLUS。
下面命令使標題語句失效 TTITLEOFF BTITLEOFF
列名 column命令定義用于顯示列名 若名字為一個單詞,不必加引號 columnenameheadingemployee
columnenameheading'employee|name' (|為換行)
取消欄定義 columnenameclear
列的格式 columnenameformatA15
columnsalformat$9,999.99
columncommlikesal
like子句,使得某一列的格式參照另一列格式,它拷貝列名及其格式
控制記錄顯示分組順序 breakondeptno (不顯示重復值)
selectdeptno,ename fromemp orderbydeptno; (ORDERBY子句用于控制BREAK)
顯示為 10clark niller 20smith scott 30allen blake
每次只有一個BREAK命令起作用,但一次可以在多個列上使用BREAK命令 breakon列名1on列名2
記錄分組 breakondeptnoskip2 selectdeptno,ename fromemp orderbydeptno;
每個deptno之間空兩行 clearbreak(取消BREAK命令) breakonpage(每次從一新頁開始) breakonreport(每次從一新報表開始) breakonpageonreport(聯合使用)
分組計算 breakondeptnoskip2 computesumofsalondeptno 計算每個部門的工資總和 skip子句使部門之間的信息分隔開
其他計算命令 computeavgofsalondeptno(平均值) count非空值的總數 MAX最大值 MIN最小值 STD標準偏差 VAR協方差 NUMBER行數
使compute命令失效 一旦定義了COMPUTE,則一直有效,直到 關閉COMPUTE(clearcompute)
SQL/PLUS環境命令 show選項 (顯示當前參數設置情況)
showall(顯示全部參數)
設置參數 set選項值或開關
setautocommiton
SET命令包括 setautocommit{off|on|immediate} (自動提交,OFF缺省)
setecho{off|on} (命令文件執行,是否在終端上顯示命令本身,OFF缺省)
setfeedback{off|on} (ON:查詢結束時,給出結果,記錄數的信息,缺省; OFF:無查詢結果,記錄數的信息)
setheading{off|on} (ON:列的頭標在報表上顯示,缺省;OFF:不在報表上顯示)
setlinesize{n} 一行顯示的最大字符數,缺省為80
setpagesize{n} 每頁的行數,缺省是14
setpause{off|on|text} (ON:當報表超過一頁時,每顯示一屏就暫停顯示,等待用戶打回車鍵,再接著顯示; OFF:頁與頁不停頓,缺省;text:頁與頁停頓,并向用戶提示信息)
SETBUFFERbuffer 設置當頭的命令緩沖區,通常情況下,SQL命令緩沖區已為當前緩沖區。 由于SQL命令緩沖區只能存放一條SQL命令, 所以可用其它緩沖區來存放SQL命令和SQL*PLUS命令。
經常用到的設置可放在login.sql文件中。
SETNULL setnull'nodata'
selectename,comm fromemp wheredeptno=30; 把部門30中無傭金雇員的傭金顯示為“NODATA”。
setnull是SQL*PLUS命令,用它來標識空值(NULL),可以設置為任意字符串。
存盤命令SAVE save文件名
input 1selectempno,ename,job 2fromemp 3wherejob='analyst'
saveresearch
目錄中會增加一個research.sql文件。
編輯命令EDIT edit
EDIT編輯當前緩沖區中的內容。
編輯一個文件 editresearch
調入命令GET getresearch 把磁盤上的文件內容調入緩沖區,并顯示在屏幕上,文件名尾不必加.sql。
START命令 運行指定的文件 startresearch
輸出命令SPOOL spooltryfile 不僅可以使查詢結果在屏幕上顯示,還可以使結果存入文件
停止向文件輸出 spooloff
把查詢結果在打印機上輸出,先把它們存入一個文件中, 然后不必使用SPOOLOFF,而用: spoolout SPOOLOUT關閉該文件并在系統缺省的打印機上輸出
制作報表舉例 edittryfile
setechooff setautocommiton setpagesize25 insertintoemp(empno,ename,hiredate) values(9999,'geiger',sysdate); insertintoemp(empno,ename,deptno) values(3333,'samson',20); spoolnew_emp select*fromemp wheredeptno=20 ordeptnoisnull / spooloff setautocommitoff
用start命令執行這個文件
-------- 6函數 字符型函數 initcap(ename);將ename中每個詞的第一個字母改為大寫。 如:jacksmith--JackSmith
length(ename);計算字符串的長度。
substr(job,1,4);
其它 lower upper least取出字符串列表中按字母排序排在最前面的一個串 greatest取出字符串列表中按字母排序排在最后的一個串
日期函數 add_month(hiredate,5)在雇傭時間上加5個月 month_between(sysdate,hiredate)計算雇傭時間與系統時間之間相差的月數 next_day(hiredate,'FRIDAY')計算受雇日期之后的第一個星期五的日期
例 selectename,sal,next_day(sysdate,'FRIDAY')as_of fromemp wheredeptno=20; (as_of是別名)
如果不用to_char函數,日期在ORACLE中的缺省格式是'DD_MON_YY' to_char(date,datepicture)
selectename,to_char(hiredate,'DyMondd,yyyy')hired fromemp wheredeptno=10;
to_date(字符串,格式)
insertintoemp(empno,ename,hiredate) values(7999,'asms',to_date('070387083000','MMDDYYHHMISS'));
日期型數據的格式 dd12 dyfri dayfriday ddspthtwelfth
mm03 monmar monthmarch
yy87 yyyy1987
例 Mar12,1987'Mondd,yyyy' MAR12,1987'MONdd,yyyy' ThursdayMARCH12'DayMONTHdd' Mar1211:00am'Monddhh:miam' Thu,thetwelfth'Dy,"the"ddspth'
算術函數 least(v1,v2)
selectename,empno,mgr,least(empno,mgr)lownum fromemp whereempno0
trunc(sal,0) 取sal的近似值(截斷)
空值函數 nvl(v1,v2) v1為列名,如果v1不是空值,nvl返回其列值。 v1為空值,返回v2的值。
聚組函數 selectsum(comm) fromemp; (返回一個匯總信息) 不能把sum用在select語句里除非用groupby
字符型、日期型、數字型的聚組函數 minmaxcount可用于任何數據類型
selectmin(ename) fromemp;
selectmin(hiredate) fromemp;
selectmin(sal) fromemp;
有多少人有工作? selectcount(job) fromemp;
有多少種不同的工種? selectcount(distinctjob) fromemp;
countdistinct計算某一字段中不同的值的個數
其它聚組函數(只用于數字型數據) avg計算平均工資 selectavg(sal) fromemp;
stddev計算工資的平均差 selectstddev(sal) fromemp;
sum計算總工資 selectsum(sal) fromemp;
groupby子句 selectdeptno,sum(sal),avg(sal) fromemp groupbydeptno;
按多個條件分組 每個部門的雇員數 selectdeptno,count(*) fromemp groupbydeptno;
每個部門的每個工種的雇員數 selectdeptno,job,count(*) fromemp groupbydeptno,job;
滿足條件的分組 (where是針對select的,having是針對groupby的) 哪些部門的工資總和超過了9000 selectdeptno,sum(sal) fromemp groupbydeptno havingsum(sal)>9000;
select小結 除去職員,哪些部門的工資總和超過了8000 selectdeptno,sum(sal) fromemp wherejob!='clerk' groupbydeptno havingsum(sal)>8000 orderbysum(sal);
--------- 7高級查詢 等值聯接 selectempno,ename,job,emp.deptno,dname fromemp,dept whereemp.deptno=dept.deptno;
外聯接 selectename,dept.deptno,loc fromemp,dept whereemp.deptno(+)=dept.deptno; 如果在dept.deptno中有的數值,在emp.deptno中沒有(如deptno=40), 則作外聯接時,結果中會產生一個空值
自聯接:同一基表的不同行要做聯接,可使用自聯接 指出每個雇員的經理名字 selectworker.ename,manager.enamemanager fromempworker,empmanager whereworker.mgr=manager.empno;
非等值聯接 哪些雇員的工資屬于第三級別 selectename,sal fromemp,salgrade wheregrade=3 andsalbetweenlosalandhisal; (基表salgrade:gradelosalhisal)
集合運算 行的連接 集合運算把2個或多個查詢結果合并為一個 union-setunion Rowsoffirstqueryplusofsecondquery,lessduplicaterows
intersect-setintersection Rowsbothquerieshaveincommon
minus-setdifference rowsuniquetothefirstquery
介紹幾個視圖 accountview enamesaljob
salesview enamesaljob
researchview enamesaljob
union運算 返回一個查詢結果中有但又不重要的行,它將基表或視圖中的記錄合并在一起 所有部門中有哪些雇員工資超過2000 對應列的數據類型必須相同 selectename,sal fromaccount wheresal>2000 union selectename,sal fromresearch wheresal>2000 union selectename,sal fromsales wheresal>2000;
intersect運算 返回查詢結果中相同的部分 各個部門中有哪些相同的工種 selectjob fromaccount intersect selectjob fromresearch intersect selectjob fromsales;
minus運算 返回在第一個查詢結果中與第二個查詢結果不相同的那部分行記錄。 有哪些工種在財會部中有,而在銷售部中沒有? selectjobfromaccount minus selectjobfromsales;
子查詢 slectename,deptno fromemp wheredeptno= (selectdeptno fromemp whereename='smith');
多級子查詢 selectename,job,sal fromemp wherejob= (selectjob fromemp whereename='clark') orsal> (selectsal fromemp whereename='clark');
多個基表與子查詢 selectename,job,sal fromemp,dept whereloc='newyork' andemp.deptno=dept.deptno andsal> (selectsal fromemp whereename='scott');
子查詢中使用聚組函數 selectename,hiredate fromemp wherehiredate= (selectmin(hiredate) fromemp);
------------ 8授權 系統權限 DBA所有權限 RESOURCE注冊,創建新的基表 CONNECT,注冊,查詢
只有DBA才有權創建新的用戶 grantconnecttoscott identifiedbytiger;
DBA或用戶自己可以改變用戶口令 grantconnecttoscott identifiedbyleopard;
基表權限1 有兩種方法獲得對基表操作的權限
創建自己的基表 獲得基表創建用戶的許可 grantselect,insert onemp toscott;
這些權限有 selectinsertupdatedeletealterindex
把所有權限授于他人 grantallonemptoscott;
同義詞 select* fromscott.emp
創建同義詞 為用戶allen的EMP基表創建同義詞employee createsynonymemployee forallen.emp
基表權限2 你可以使其他用戶有這樣的權力,即其他用戶可以把你的基表權限授予他人 grantall onemp toscott withgrantoption;
收回權限 系統權限只有被DBA收回
基表權限隨時都可以收回
revokeinsert onemp fromscott;
--------- 9索引 建立索引 createindexemp_ename onemp(ename);
刪除索引 dropindexemp_ename;
關于索引 只對較大的基表建立索引(至少50條記錄) 建立索引之前插入數據 對一個基表可建立任意多個索引 一般是在作為主鍵的列上建立索引 建立索引之后,不影響SQL命令的執行 建立索引之后,ORACLE自動維護和使用索引
保證數據唯一性 提高執行速度的同時,索引還可以保證每個記錄中的每個列值是不重復的。 createuniqueindexemp_empno onemp(empno);
-------- 練習和答案
有沒有工資比獎金多的雇員?如果有,按工資的降序排列。 如果有兩個以上的雇員工資相同,按他們的名字排序。 selectenameemployee,salsalary,commcommision fromemp wheresal>comm orderbysaldesc,ename;
列出有關雇員姓名、獎金占收百分比的信息。 要求顯示時列名意義明確,按雇員姓名排序,不包括獎金未知的雇員。 selectenameemployee,(comm/(comm+sal))*100incentive fromemp wherecommisnotnull orderbyename;
在chicago(部門30)工作的所有雇員的工資上漲10%。 updateemp setsal=1.1*sal wheredeptno=30;
updateemp setsal=1.1*sal wheredeptno=(selectdeptno fromdept whereloc='chicago');
為hitech公司新建一個部門,編號為50,其它信息均不可知。 insertintodept(dname,deptno) values('faclities',50);
創建視圖,三個列名,其中不包括職員信息 createviewemployee("employeename", "employeenumber", "employeejob") asselectename,empno,job fromemp wherejob!='clerk';
制作工資報表,包括雇員姓名、受雇時間(按星期計算),工資和部門編號, 一頁顯示一個部門的信息,每頁尾,顯示該頁的工資之和以及受雇時間之和, 報表結尾處,顯示所有雇員的工資總和以及受雇時間總和, 工資按美元計算,受雇時間按星期計算,每頁的上方應有標題。 ttitle'service' breakondeptnoonpageonreport computesumofsalondeptno computesumofsalonreport computesumofservice_lengthondeptno computesumofservice_lengthonreport columnsalformat$99,999.00 columnservice_lengthformat9999 selectdeptno,enameemployee,(sysdate-hiredate)/7service_length,sal fromemp orderbydeptno;
制作報表,包括雇員姓名、總收入和受傭日期, 且:姓名的第一個字母必須大寫,雇傭日期格式為MM/DD/YYYY, 總收入包括沒有獎金的雇員的總收入,姓名按字母順序排列。 col"hiredate"formatA12 col"employee"formatA10 col"compensation"format$99,999.00 selectinitcap(ename)"employee", (sal+nvl(comm,0))"compensation", to_char(hiredate,'MM/DD/YYYY')"hiredate" fromemp orderbyename;
列出有超過7個周邊國家的國家名字和面積。 selectnation,area fromnation wherecodein (selectnation_code fromborder groupbynation_code havingcount(*)>7);
列出所有面積大于等于日本的島國的國名和人口。 selectnation,population fromnation,border wherecode=nation_code(+) andnation_codeisnull andarea>= (selectarea fromnation whereupper(nation)='JAPAN');
列出所有邊界在其它國家中的國名,并且顯示其邊界國家名字。 breakonnation selectnation1.nation, nation2.nationborderin_country fromnationnation1,border,nationnation2 wherenation1.code=border.nation_code andborder.border_code=nation2.code orderbynation1.nation;
----------- ----------- PL/SQL
2PL/SQL的塊結構和數據類型
塊結構的特點 嵌套 begin ...... begin ...... exception ...... end; exception ...... end;
標識符: 不能超過30個字符 第一個字符必須為字母 其余字符可以是字母,數字,$,_,或# 不區分大小寫形式 如果用雙引號括起來,則字符順序可以任意排列,并區分大小寫形式 無SQL保留字
數據類型 數字型: 整數,實數,以及指數
字符串: 用單引號括起來 若在字符串表示單引號,則使用兩個單引號 字符串長度為零(兩個單引號之間沒有字符),則表示NULL
字符: 長度為1的字符串
數據定義 語法 標識符[常數>數據類型[NOTNULL>[:=PL/SQL表達式>; ':='表示給變量賦值
數據類型包括 數字型number(7,2) 字符型char(120) 日期型date 布爾型boolean(取值為true,false或null,不存貯在數據庫中)
日期型 anniversarydate:='05-JUL-95'; project_completiondate;
布爾型 over_budgetbooleannotnull:=false; availableboolean; (初始值為NULL)
%type類型匹配 books_printednumber(6); books_soldbook_printed%type; manager_nameemp.ename%type;
變量賦值 變量名:=PL/SQL表達式 numvar:=5; boolvar:=true; datevar:='11-JUN-87';
字符型、數字型表達式中的空值 null+<數字>=null(空值加數字仍是空值) null><數字>=null(空值與數字進行比較,結果仍是空值) null||'字符串'='字符串'(null即'') (空值與字符串進行連接運算,結果為原字符串)
變量作用范圍 標識符在宣言它的塊中有效 標識符如果不在子塊中重新定義,則在PL/SQL塊的所有子塊中同樣有效 重新定義后的標識符,作用范圍僅在本子塊中有效
例 declare e_messchar(80); begin /*子塊1*/ declare v1number(4); begin selectempnointov1fromemp wherejob='president'; exception whentoo_many_rowsthen insertintojob_errors values('morethanonepresident'); end; /*子塊2*/ declare v1number(4); begin selectempnointov1fromemp wherejob='manager'; exception whentoo_many_rowsthen insertintojob_errors values('morethanonemanager'); end; exception whenothersthen e_mess:=substr(sqlerrm,1,80); insertintogeneralerrorsvalues(e_mess); end;
--------- 3SQL和PL/SQL
插入 declare my_salnumber(7,2):=3040.55; my_enamechar(25):='wanda'; my_hiredatedate:='08-SEP-88'; begin insertintoemp (empno,enmae,job,hiredate,sal,deptno) values(2741,my_ename,'cabdriver',my_hiredate,my_sal,20); end;
刪除 declare bad_child_typechar(20):='naughty'; begin deletefromsantas_gift_listwhere kid_rating=bad_child_type; end;
事務處理 commit[WORK>; rollback[WORK>; (關鍵字WORK可選,但對命令執行無任何影響) savepoint標記名;(保存當前點) 在事務中標記當前點 rollback[WORK>to[SAVEPOINT>標記名;(回退到當前保存點) 取消savepoint命令之后的所有對數據庫的修改 關鍵字WORK和SAVEPOINT為可選項,對命令執行無任何影響
函數 PL/SQL塊中可以使用SQL命令的所有函數 insertintophonebook(lastname)value(upper(my_lastname)); selectavg(sal)intoavg_salfromemp;
對于非SQL命令,可使用大多數個體函數 不能使用聚組函數和參數個數不定的函數,如 x:=sqrt(y); lastname:=upper(lastname); age_diff:=months_between(birthday1,birthday2)/12;
賦值時的數據類型轉換 4種賦值形式: 變量名:=表達式 insertinto基表名values(表達式1,表達式2,...); update基表名set列名=表達式; select列名into變量名from...;
數據類型間能進行轉換的有: char轉成number number轉成char char轉成date date轉成char
例 char_var:=nm_var; 數字型轉換成字符型 date_var:='25-DEC-88'; 字符型轉換成日期型 insertinto表名(num_col)values('604badnumber'); 錯誤,無法成功地轉換數據類型
--------- 4條件控制 例 declare num_jobsnumber(4); begin selectcount(*)intonum_jobsfromauditions whereactorid=&&actor_idandcalled_back='yes'; ifnum_jobs>100then updateactorsetactor_rating='wordclass' whereactorid=&&actor_id; elsifnum_job=75then updateactorsetactor_rating='daytimesoaps' whereactorid=&&actor_id; else updateactorsetactor_rating='waiter' whereactorid=&&actor_id; endif; endif; commit; end;
-------- 5循環 語法 loop ...... endloop; exit;(退出循環) exit[when>;(退出循環,當滿足WHEN時) 例1 declare ctrnumber(3):=0; begin loop insertintotable1values('tastesgreat'); insertintotable2values('lessfilling'); ctr:=ctr+1; exitwhenctr=100; endloop; end; (注:如果ctr取為NULL,循環無法結束)
例2 FOR語法 for變量<范圍>loop ...... endloop;
declare my_indexchar(20):='fettucinialfredo'; bowlchar(20); begin formy_indexinreverse21..30loop insertintotemp(coll)values(my_index); /*循環次數從30到21*/ endloop; bowl:=my_index; end; 跟在inreverse后面的數字必須是從小到大的順序,必須是整數,不能是變量或表達式
---------- 6游標 顯式游標
打開游標 open<游標名> 例 opencolor_cur;
游標屬性 %notfound %found %rowcount %isopen 例 fetchmy_curintomy_var; whilemy_cur%foundloop (處理數據) fetchmy_curintomy_var; exitwhenmy_cur%rowcount=10; endloop;
%notfound屬性 取值情況如下: fetch操作沒有返回記錄,則取值為true fetch操作返回一條記錄,則取值為false 對游標無fetch操作時,取值為null <游標名>%notfound 例 ifcolor_cur%notfoundthen... 注:如果沒有fetch操作,則<游標名>%notfound將導致出錯, 因為%notfound的初始值為NULL。
關閉游標 close<游標名> 例 closecolor_cur;
游標的FOR循環 語法 for<記錄名>in<游標名>loop <一組命令> endloop; 其中: 索引是建立在每條記錄的值之上的 記錄名不必聲明 每個值對應的是記錄名,列名 初始化游標指打開游標 活動集合中的記錄自動完成FETCH操作 退出循環,關閉游標
隱式游標 隱式游標是指SQL命令中用到的,沒有明確定義的游標 insert,update,delete,select語句中不必明確定義游標 調用格式為SQL% 存貯有關最新一條SQL命令的處理信息
隱式游標的屬性 隱式游標有四個屬性 SQL%NOTFOUND SQL%FOUND SQL%ROWCOUNT:隱式游標包括的記錄數 例: deletefrombaseball_teamwherebatting_avg<100; ifsql%rowcount>5thn insertintotemp values('yourteamneedshelp'); endif;
SQL%ISOPEN:取值總為FALSE。SQL命令執行完畢,PL/SQL立即關閉隱式游標。
--------- 7標號 GOTO語句 用法: gotoyou_are_here; 其中you_are_here是要跳轉的語句標號 標號必須在同一組命令,或是同一塊中使用
正確的使用 <>(標號) x:=x+1 ifa>bthen b:=b+c; gotodinner; endif;
錯誤的使用 gotojail; ifa>bthen b:=b+c; <>(標號) x:=x+1; endif;
標號:解決意義模糊 標號可用于定義列值的變量 <> declare deptnonumber:=20; begin updateempsetsal=sal*1.1 wheredeptno=sample.deptno; commit; endsample; 如果不用標號和標號限制符,這條命令將修改每條記錄。
---------- 8異常處理 預定義的異常情況 任何ORACLE錯誤都將自動產生一個異常信息 一些異常情況已命名,如: no_data_found當SELECT語句無返回記錄時產生 too_many_rows沒有定義游標,而SELECT語句返回多條記錄時產生 whenevernotfound無對應的記錄
用戶定義的異常情況 由用戶自己獲取 在DECLARE部分定義: declare xnumber; something_isnt_rightexception; 用戶定義的異常情況遵循一般的作用范圍規則 條件滿足時,獲取異常情況:raisesomething_isnt_right 注意:同樣可以獲取預定義的異常情況
exception_init語句 允許為ORACLE錯誤命名
調用格式: pragmaexception_init(<表達式>,); 例 declare deadlock_detectedexception; pragmaexception_init(deadlock_detected,-60);
raise語句 單獨使用RAISE命令,可再一次獲取當前的異常情況(就象異常情況被重復處理了一樣)。 在異常處理中,此語句只能單獨使用。
異常處理標識符 一組用于處理異常情況的語句: exception when<表達式>or[表達式...>then <一組語句> ... whenothersthen--最后一個處理 <一組語句> end;既結束PL/SQL塊部分,也結束異常處理部分
-------- 練習與答案 1: 接收contract_no和item_no值,在inventory表中查找,如果產品: 已發貨,在arrival_date中賦值為今天后的7天 已訂貨,在arrival_date中賦值為今天后的一個月 既無訂貨又無發貨,則在arrival_date中賦值為今天后的兩個月, 并在order表中增加一條新的訂單記錄。
product_status的列值為'shipped'和'ordered'
inventory: product_idnumber(6) product_descriptionchar(30) product_statuschar(20) std_shipping_qtynumber(3)
contract_item: contract_nonumber(12) item_nonumber(6) arrival_datedate
order: order_idnumber(6) product_idnumber(6) qtynumber(3)
答案: declare i_product_idinventory.product_id%type; i_product_descriptioninventory.product_description%type; i_product_statusinventory.product_status%type; i_std_shipping_qtyinventory.std_shipping_qty%type;
begin selectproduct_id,product_description,product_status,std_shipping_qty intoi_product_id,i_product_description, i_product_status,i_std_shipping_qty frominventory whereproduct_id=( selectproduct_id fromcontract_item wherecontract_no=&&contractnoanditem_no=&&itemno); ifi_product_status='shipped'then updatecontract_item setarrival_date=sysdate+7 whereitem_no=&&itemnoandcontract_no=&&contractno; elsifi_product_status='ordered'then updatecontract_item setarrival_date=add_months(sysdate,1) whereitem_no=&&itemnoandcontract_no=&&contractno; else updatecontract_item setarrival_date=add_months(sysdate,2) whereitem_no=&&itemnoandcontract_no=&&contractno; insertintoorders values(100,i_product_id,i_std_shipping_qty); endif; endif; commit; end;
2: 1.找出指定部門中的所有雇員 2.用帶'&'的變量提示用戶輸入部門編號 3.把雇員姓名及工資存入prnttable表中,基結構為: createtableprnttable (seqnumber(7),linechar(80)); 4.異常情況為,部門中獎金不為空值的雇員信息才能存入prnttable表中。
答案: declare cursoremp_curis selectename,sal,comm fromempwheredeptno=&dno; emp_recemp_cur%rowtype; null_commissionexception; begin openemp_cur; fetchemp_curintoemp_rec; while(emp_cur%found)loop ifemp_rec.commisnullthen begin closeemp_cur; raisenull_commission; end; endif; fetchemp_curintoemp_rec; endloop; closeemp_sur; exception whennull_commissionthen openemp_cur; fetchemp_curintoemp_rec; while(emp_cur%found)loop ifemp_rec.commisnotnullthen insertintotempvalues(emp_rec.sal,emp_rec.ename); endif; fetchemp_curintoemp_rec; endloop; closeemp_cur; commit; end;
Java研究組織-版權所有2002-2002
?
作者:UB時間:2003-08-14 21:06:59 [修改][回復][刪除]ORACLE數據庫對象與用戶管理 一、 ORACLE數據庫的模式對象的管理與維護 本節的主要內容是關于 ORACLE數據庫的模式對象的管理與維護,這些模式對象包括:表空間、表、視圖、索引、序列、同義詞、聚集和完整性約束。對于每一個模式對象,首先描述了它的定義,說明了它的功能,最后以基于 SQL語言的實例說明如何對它們進行管理于維護。 1.1表空間 由于表空間是包含這些模式對象的邏輯空間,有必要先對它進行維護。 創建表空間 SQL>CREATETABLESPACEjxzy >DATAFILE‘/usr/ oracle/dbs/jxzy.dbf’ >ONLINE; 修改表空間 SQL>ALTERTABLESPACEjxzyOFFLINENORMAL; SQL>ALTERTABLESPACEjxzy >RENAMEDATAFILE‘/usr/ oracle/dbs/jxzy.dbf’ >TO‘/usr/ oracle/dbs/jxzynew.dbf’ >ONLINE SQL>CREATETABLESPACEjxzyONLINE 刪除表空間 SQL>DROPTABLESPACEjxzy >INCLUDINGCONTENTS 1.2表維護 表是數據庫中數據存儲的基本單位,一個表包含若干列,每列具有列名、類型、長度等。 表的建立 SQL>CREATETABLEjxzy.switch( >OFFICE_NUMNUMBER(3,0)NOTNULL, >SWITCH_CODENUMBER(8,0)NOTNULL, >SWITCH_NAMEVARCHAR2(20)NOTNULL); 表的修改 SQL>ALTERTABLEjxzy.switch >ADD(DESCVARCHAR2(30)); 表的刪除 SQL>DROPTABLEjxzy.switch >CASCADECONSTRAINTS //刪除引用該表的其它表的完整性約束 1.3視圖維護 視圖是由一個或若干基表產生的數據集合,但視圖不占存儲空間。建立視圖可以保護數據安全(僅讓用戶查詢修改可以看見的一些行列)、簡化查詢操作、保護數據的獨立性。 視圖的建立 SQL>CREATEVIEWjxzy.pole_well_viewAS >(SELECTpole_path_numASpath, poleASdevice_numFROMpole >UNION >SELECTpipe_path_numASpath, >wellASdevice_numFROMwell); 視圖的替換 SQL>REPLACEVIEWjxzy.pole_well_viewAS >(SELECTpole_path_numASpath, poleASsupport_deviceFROMpole >UNION >SELECTpipe_path_numASpath, wellASsupport_deviceFROMwell); 視圖的刪除 SQL>DROPVIEWjxzy.pole_well_view; 1.4序列維護 序列是由序列發生器生成的唯一的整數。 序列的建立 SQL>CREATESEQUENCEjxzy.sequence_cable >STARTWITH1 >INCREMENTBY1 >NO_MAXVALUE; 建立了一個序列,jxzy.sequence_cable.currval返回當前值,jxzy.sequence_cable.nextval返回當前值加1后的新值 序列的修改 SQL>ALTERSEQUENCEjxzy.sequence_cable >STARTWITH1//起點不能修改,若修改,應先刪除,然后重新定義 >INCTEMENTBY2 >MAXVALUE1000; 序列的刪除 SQL>DROPSEQUENCEjxzy.sequence_cable 1.5索引維護 索引是與表相關的一種結構,它是為了提高數據的檢索速度而建立的。因此,為了提高表上的索引速度,可在表上建立一個或多個索引,一個索引可建立在一個或幾個列上。 對查詢型的表,建立多個索引會大大提高查詢速度,對更新型的表,如果索引過多,會增大開銷。 索引分唯一索引和非唯一索引 索引的建立 SQL>CREATEINDEXjxzy.idx_switch >ONswitch(switch_name) >TABLESPACEjxzy; 索引的修改 SQL>ALTERINDEXjxzy.idx_switch >ONswitch(office_num,switch_name) >TABLESPACEjxzy; 索引的刪除 SQL>DROPINDEXjxzy.idx_switch; 1.6完整性約束管理 數據庫數據的完整性指數據的正確性和相容性。數據完整型檢查防止數據庫中存在不符合語義的數據。 完整性約束是對表的列定義一組規則說明方法。 ORACLE提供如下的完整性約束. a.NOTNULL非空 b.UNIQUE唯一關鍵字 c.PRIMATYKEY主鍵一個表只能有一個,非空 d.FOREIGAKEY外鍵 e.CHECK表的每一行對指定條件必須是true或未知(對于空值) 例如: 某列定義非空約束 SQL>ALTERTABLEoffice_organization >MODIFY(descVARCHAR2(20) >CONSTRAINTnn_descNOTNULL) 某列定義唯一關鍵字 SQL>ALTERTABLEoffice_organization >MODIFY(office_nameVATCHAR2(20) >CONSTRAINTuq_officenameUNIQUE) 定義主鍵約束,主鍵要求非空 SQL>CREATETABLEswitch(switch_codeNUMBER(8) >CONSTRAINTpk_switchcodePRIMARYKEY,) 使主鍵約束無效 SQL>ALTERTABLEswitchDISABLEPRIMARYKEY 定義外鍵 SQL>CREATETABLEPOLE(pole_codeNUMBER(8), >office_numnumber(3) >CONSTRAINTfk_officenum >REFERENCESoffice_organization(office_num) >ONDELETECASCADE); 定義檢查 SQL>CREATETABLEoffice_organization( >office_numNUMBER(3), >CONSTRAINTcheck_officenum >CHECK(office_numBETWEEN10AND99); 二、 ORACLE數據庫用戶與權限管理 ORACLE是多用戶系統,它允許許多用戶共享系統資源。為了保證數據庫系統的安全,數據庫管理系統配置了良好的安全機制。 2.1 ORACLE數據庫安全策略 建立系統級的安全保證 系統級特權是通過授予用戶系統級的權利來實現,系統級的權利(系統特權)包括:建立表空間、建立用戶、修改用戶的權利、刪除用戶等。系統特權可授予用戶,也可以隨時回收。 ORACLE系統特權有80多種。 建立對象級的安全保證 對象級特權通過授予用戶對數據庫中特定的表、視圖、序列等進行操作(查詢、增、刪改)的權利來實現。 建立用戶級的安全保證 用戶級安全保障通過用戶口令和角色機制(一組權利)來實現。引入角色機制的目的是簡化對用戶的授權與管理。做法是把用戶按照其功能分組,為每個用戶建立角色,然后把角色分配給用戶,具有同樣角色的用戶有相同的特權。 2.2用戶管理 ORACLE用戶管理的內容主要包括用戶的建立、修改和刪除 用戶的建立 SQL>CREATEUSERjxzy >IDENTIFIEDBYjxzy_password >DEFAULTTABLESPACEsystem >QUATA5MONsystem;//供用戶使用的最大空間限額 用戶的修改 SQL>CREATEUSERjxzy >IDENTIFIEDBYjxzy_pw >QUATA10MONsystem; 刪除用戶及其所建對象 SQL>DROPUSERjxzyCASCADE;//同時刪除其建立的實體 2.3系統特權管理與控制 ORACLE提供了80多種系統特權,其中每一個系統特權允許用戶執行一個或一類數據庫操作。 授予系統特權 SQL>GRANTCREATEUSER,ALTERUSER,DROPUSER >TOjxzy_new >WITHADMINOPTION; 回收系統特權 SQL>REVOKECREATEUSER,ALTERUSER,DROPUSER >FROMjxzy_new //但沒有級聯回收功能 顯示已被授予的系統特權(某用戶的系統級特權) SQL>SELECT*FROMsys.dba_sys_privs 2.4對象特權管理與控制 ORACLE對象特權指用戶在指定的表上進行特殊操作的權利。這些特殊操作包括增、刪、改、查看、執行(存儲過程)、引用(其它表字段作為外鍵)、索引等。 授予對象特權 SQL>GRANTSELECT,INSERT(office_num,office_name), >UPDATE(desc)ONoffice_organization >TOnew_adminidtrator >WITHGRANTOPTION; //級聯授權 SQL>GRANTALLONoffice_organization >TOnew_administrator 回收對象特權 SQL>REVOKEUPDATEONoffice_orgaization >FROMnew_administrator //有級聯回收功能 SQL>REVOKEALLONoffice_organization >FROMnew_administrator 顯示已被授予的全部對象特權 SQL>SELECT*FROMsys.dba_tab_privs 2.5角色的管理 ORACLE的角色是命名的相關特權組(包括系統特權與對象特權), ORACLE用它來簡化特權管理,可把它授予用戶或其它角色。 ORACLE數據庫系統預先定義了CONNECT、RESOURCE、DBA、EXP_FULL_DATABASE、IMP_FULL_DATABASE五個角色。CONNECT具有創建表、視圖、序列等特權;RESOURCE具有創建過程、觸發器、表、序列等特權、DBA具有全部系統特權;EXP_FULL_DATABASE、IMP_FULL_DATABASE具有卸出與裝入數據庫的特權。 通過查詢sys.dba_sys_privs可以了解每種角色擁有的權利。 授予用戶角色 SQL>GRANTDBATOnew_administractor >WITHGRANTOPTION;
最大值 select greatest(jjkxd_sysj,slkxd_sysj,sp_lgfstl_sysj) from wx_ysjcsj where jh_id=6
最小值 select least(jjkxd_sysj,slkxd_sysj,sp_lgfstl_sysj) from wx_ysjcsj where jh_id=6
|