oracle創建表空間

ORACLE中,表空間是數據管理的基本方法,所有用戶的對象要存放在表空間中,也就是用戶有空間的使用權,才能創建用戶對象.否則是不充許創建對象,因爲就是想創建對象,如表,索引等,也沒有地方存放,Oracle會提示:沒有存儲配額.
  因此,在創建對象之前,首先要分配存儲空間.
  分配存儲,就要創建表空間:
  創建表空間示例如下:
CREATE TABLESPACE "SAMPLE"
LOGGING
DATAFILE 'D:\ORACLE\ORADATA\ORA92\LUNTAN.ora' SIZE 5M
EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO
上面的語句分以下幾部分:
第一: CREATE TABLESPACE "SAMPLE"  創建一個名爲 "SAMPLE" 的表空間.
對錶空間的命名,遵守Oracle 的命名規範就可了.
ORACLE可以創建的表空間有三種類型:
(1)TEMPORARY: 臨時表空間,用於臨時數據的存放;
創建臨時表空間的語法如下:
CREATE TEMPORARY TABLESPACE "SAMPLE"......
(2)UNDO : 還原表空間. 用於存入重做日誌文件.
創建還原表空間的語法如下:
CREATE UNDO TABLESPACE "SAMPLE"......
(3)用戶表空間: 最重要,也是用於存放用戶數據表空間
可以直接寫成: CREATE TABLESPACE "SAMPLE"
TEMPORARY 和 UNDO 表空間是ORACLE 管理的特殊的表空間.只用於存放系統相關數據.
第二: LOGGING
有 NOLOGGING 和 LOGGING 兩個選項,
NOLOGGING: 創建表空間時,不創建重做日誌.
LOGGING 和NOLOGGING正好相反, 就是在創建表空間時生成重做日誌.
用NOLOGGING時,好處在於創建時不用生成日誌,這樣表空間的創建較快,但是沒能日誌,數據丟失後,不能恢復,但是一般我們在創建表空間時,是沒有數據的,按通常的做法,是建完表空間,並導入數據後,是要對數據做備份的,所以通常不需要表空間的創建日誌,因此,在創建表空間時,選擇 NOLOGGING,以加快表空間的創建速度.
第三: DATAFILE 用於指定數據文件的具體位置和大小.
如: DATAFILE 'D:\ORACLE\ORADATA\ORA92\LUNTAN.ora' SIZE 5M
說明文件的存放位置是 'D:\ORACLE\ORADATA\ORA92\LUNTAN.ora' , 文件的大小爲5M.
如果有多個文件,可以用逗號隔開:
DATAFILE 'D:\ORACLE\ORADATA\ORA92\LUNTAN.ora' SIZE 5M,
'D:\ORACLE\ORADATA\ORA92\dd.ora' SIZE 5M
但是每個文件都需要指明大小.單位以指定的單位爲準如 5M 或 500K.
對具體的文件,可以根據不同的需要,存放大不同的介質上,如磁盤陣列,以減少IO竟爭.
指定文件名時,必須爲絕對地址,不能使用相對地址.
第四: EXTENT MANAGEMENT LOCAL 存儲區管理方法
在Oracle 8i以前,可以有兩種選擇,一種是在字典中管理(DICTIONARY),另一種是本地管理(LOCAL ),從9I開始,只能是本地管理方式.因爲LOCAL 管理方式有很多優點.
在字典中管理(DICTIONARY): 將數據文件中的每一個存儲單元做爲一條記錄,所以在做DM操作時,就會產生大量的對這個管理表的Delete和Update操作.做大量數據管理時,將會產生很多的DM操作,嚴得的影響性能,同時,長時間對錶數據的操作,會產生很多的磁盤碎片,這就是爲什麼要做磁盤整理的原因.
本地管理(LOCAL): 用二進制的方式管理磁盤,有很高的效率,同進能最大限度的使用磁盤. 同時能夠自動跟蹤記錄臨近空閒空間的情況,避免進行空閒區的合併操作。
第五: SEGMENT SPACE MANAGEMENT
磁盤擴展管理方法:
SEGMENT SPACE MANAGEMENT: 使用該選項時區大小由系統自動確定。由於 Oracle 可確定各區的最佳大小,所以區大小是可變的。
UNIFORM SEGMENT SPACE MANAGEMENT:指定區大小,也可使用默認值 (1 MB)。
第六: 段空間的管理方式:
AUTO: 只能使用在本地管理的表空間中. 使用LOCAL管理表空間時,數據塊中的空閒空間增加或減少後,其新狀態都會在位圖中反映出來。位圖使 Oracle 管理空閒空間的行爲更加自動化,併爲管理空閒空間提供了更好的性,但對含有LOB字段的表不能自動管理.
MANUAL: 目前已不用,主要是爲向後兼容.
第七: 指定塊大小. 可以具體指定表空間數據塊的大小.
創建例子如下:
1 CREATE TABLESPACE "SAMPLE"
2 LOGGING
3 DATAFILE 'D:\ORACLE\ORADATA\ORA92\SAMPLE.ora' SIZE 5M,
4 'D:\ORACLE\ORADATA\ORA92\dd.ora' SIZE 5M
5 EXTENT MANAGEMENT LOCAL
6 UNIFORM SEGMENT SPACE MANAGEMENT
7* AUTO
SQL> /
表空間已創建。
要刪除表空間進,可以
SQL> DROP TABLESPACE SAMPLE;
表空間已丟棄。

oracle調整表空間文件大小

1、調整表空間文件大小

alter database datafile '/u01/app/oracle/oradata/rmanrep/users01.dbf' resize 15m;

2、調整表空間文件自動擴展
alter database datafile '/u01/app/oracle/oradata/rmanrep/users01.dbf' autoextend on
next 20m maxsize 1g;

3、新增磁盤
alter database datafile '/u01/app/oracle/oradata/rmanrep/users01.dbf' autoextend on
next 20m maxsize 1g;

alter tablespace users add datafile '/u03/oradata/users02.dbf' size 50m
autoextend on next 10m maxsize 200m
Oracle創建用戶/密碼並授權 移除權限
oracle 2011-01-21 16:45:38 閱讀86 評論0 字號:大中小 訂閱
Oracle創建用戶/密碼並授權
(1) 創建用戶
Create user 用戶名 identified by 密碼;(如果是數字則要加雙引號”111111”,如果是字母就不用)
(2) 授權給某個用戶
Grant connect,resource to 用戶名;(只有用戶有了connect 和 resource後才能操作其他表)
(3) 授DBA 權限
Grant dba to 用戶名;
(4) 給用戶創建會話的權限:
grant create session to DB_USER
(3) 授DBA 權限
Grant dba to 用戶名;
(4) 撤權:
revoke 權限... from 用戶名;
(5)刪除用戶:
drop user username cascade (cascade 保證徹底刪除)
首先用管理員的帳戶登錄(要有修改用戶的權限)system
alter user sys identified by 123; (sys是用戶名,123是密碼)
如果用sys登錄:
connect sys/oralce as sysdba;
用system登錄:
connect system/oracle;

oracle用戶權限
2008-03-18 10:04
Oracle系統中用戶權限的賦予,查看和管理.
在Oracle數據庫中,用戶的權限分爲兩種(在這裏我們不討論dba或oper的權限,只考慮普通用戶的權限),分別是System Privilege系統權限 和User Table Privilege用戶數據表權限.
1.首先,創建用戶,以下幾條命令可以創建一個用戶,前提是必須以DBA的身份登錄(如果你不是DBA,不要看下去了):
create user DB_USER identified by DB_USER_PW '創建用戶DB_USER,密碼爲DB_USER_PW
grant create session to DB_USER '給用戶創建會話的權限
grant resource to DB_USER
2.當用戶建立後,會自動在Oracle數據庫系統中生成屬於該用戶的Scheme (可以理解爲所有屬於該用戶的表,視圖....等對象的集合).
該用戶可以將對這些對象的訪問權限賦予其它的系統用戶.
3.該用戶用sqlplus登錄後,以下命令可以看到該用戶的權限(該部分取自於CNOUG網站):
本用戶讀取其他用戶對象的權限:
  select from user_tab_privs;
本用戶所擁有的系統權限:
  select
from user_sys_privs;
ORACLE數據庫用戶與權限管理
ORACLE是多用戶系統,它允許許多用戶共享系統資源。爲了保證數據庫系統的安全,數據庫管理系統配置了良好的安全機制。

  1. 1 ORACLE數據庫安全策略
    建立系統級的安全保證
    系統級特權是通過授予用戶系統級的權利來實現,系統級的權利(系統特權)包括:建立表空間、建立用戶、修改用戶的權利、刪除用戶等。系統特權可授予用戶,也可以隨時回收。ORACLE系統特權有80多種。
    建立對象級的安全保證
    對象級特權通過授予用戶對數據庫中特定的表、視圖、序列等進行操作(查詢、增、刪改)的權利來實現。
    建立用戶級的安全保證
    用戶級安全保障通過用戶口令和角色機制(一組權利)來實現。引入角色機制的目的是簡化對用戶的授權與管理。做法是把用戶按照其功能分組,爲每個用戶建立角色,然後把角色分配給用戶,具有同樣角色的用戶有相同的特權。
    2.2 用戶管理
    ORACLE用戶管理的內容主要包括用戶的建立、修改和刪除
    用戶的建立
    SQL>CREATE USER jxzy

    IDENTIFIED BY jxzy_password
    DEFAULT TABLESPACE system
    QUATA 5M ON system; //供用戶使用的最大空間限額
    用戶的修改
    SQL>CREATE USER jxzy
    IDENTIFIED BY jxzy_pw
    QUATA 10M ON system;
    刪除用戶及其所建對象
    SQL>DROP USER jxzy CASCADE; //同時刪除其建立的實體
    2.3系統特權管理與控制
    ORACLE 提供了80多種系統特權,其中每一個系統特權允許用戶執行一個或一類數據庫操作。
    授予系統特權
    SQL>GRANT CREATE USER,ALTER USER,DROP USER
    TO jxzy_new
    WITH ADMIN OPTION;
    回收系統特權
    SQL>REVOKE CREATE USER,ALTER USER,DROP USER
    FROM jxzy_new
    //但沒有級聯回收功能
    顯示已被授予的系統特權(某用戶的系統級特權)
    SQL>SELECTFROM sys.dba_sys_privs
    2.4 對象特權管理與控制
    ORACLE對象特權指用戶在指定的表上進行特殊操作的權利。這些特殊操作包括增、刪、改、查看、執行(存儲過程)、引用(其它表字段作爲外鍵)、索引等。
    授予對象特權
    SQL>GRANT SELECT,INSERT(office_num,office_name),
    UPDATE(desc)ON office_organization
    TO new_adminidtrator
    WITH GRANT OPTION;
    //級聯授權
    SQL>GRANT ALL ON office_organization
    TO new_administrator
    回收對象特權
    SQL>REVOKE UPDATE ON office_orgaization
    FROM new_administrator
    //有級聯回收功能
    SQL>REVOKE ALL ON office_organization
    FROM new_administrator
    顯示已被授予的全部對象特權
    SQL>SELECT
    FROM sys.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>GRANT DBA TO new_administractor
    WITH GRANT OPTION;

    Oracle 的用戶根據所被授予的權限分爲系統權限和對象權限。其中最高的權限是sysdba。 Sysdba具有控制Oracle一切行爲的特權,諸如創建、啓動、關閉、恢復數據庫,使數據庫歸檔/非歸檔,備份表空間等關鍵性的動作只能通過具有sysdba權限的用戶來執行。這些任務即使是普通DBA角色也不行。Sysoper是一個與sysdba相似的權限,只不過比sysdba少了SYSOPER privileges WITH ADMIN OPTION,CREATE DATABASE,RECOVER DATABASE UNTIL這幾個權限而已。這兩者的認證方式是相同的辦法,所以下面只介紹sysdba的認證管理。
      一般對sysdba的管理有兩種方式: 作系統認證和密碼文件認證。具體選擇那一種認證方式取決於:你是想在Oracle運行的機器上維護數據庫,還是在一臺機器上管理分佈於不同機器上的所有的Oracle數據庫。若選擇在本機維護數據庫,則選擇 作系統認證可能是一個簡單易行的辦法;若有好多數據庫,想進行集中管理,則可以選擇password文件認證方式。
      下圖比較直觀的說明了這個選擇權衡過程:
      
      使用 作系統認證方式的配置過程:
      1. 在
    作系統中建立一個合法帳戶。
      具體來說,在NT上,首先建立一個本地用戶組,取名爲ORA__DBA,其中SID爲該數據庫實例的SID,或者建立一個ORA_DBA地組,該組不對應於任何一個單獨的Oracle實例。這樣當一個NT上有好幾個Oracle實例時,不用分別管理。然後再NT上建立一個用戶,並且把它歸入該組中。但是實際上這兩步在Oracle8I安裝過程中已經自動完成了,一般不用手動進行。
      第三步:在sqlnet.ora(位於$ORACLEHOME/NETWORK/ADMIN目錄中)中,把SQLNET.AUTHENTICATION  SERVICES 設置爲SQLNET.AUTHENTICATION_SERVICES= (NTS),意思爲使用NT認證方式。
      第四步,在INIT.ORA中,把REMOTE_LOGIN_PASSWORD設置爲NONE,意思是不用password認證方式。
      完成以上步驟後,就可以在登錄到NT後,直接在SQL*Plus 和SERVER MANAGER中CONNECT INTERNAL (CONNECT / AS SYSDBA)來作爲超級用戶登錄到Oracle中,執行一些只有超級用戶才能進行的 作。
      在Unix下,情況有些不同。畢竟這是兩個完全不同的
    作系統。
      首先,在安裝Oracle之前,建立一個DBA組,這一步不用說了,不然是裝不上Oracle的。一般還建立一個名爲Oracle的用戶,並把它加入到DBA組中。
      第二步, 設置REMOTE_LOGIN_PASSWORD爲NONE。在Oracle8.1以後,該參數默認爲EXCLUSIVE。一定要記得改過來。
      第三步, 用該用戶名登錄Unix,運行SQLPlus 或者SERVER MANAGER,輸入以下命令:CONNECT INTERNAL (CONNECT / AS SYSDBA)來登錄到Oracle中。
      使用password文件認證的具體步驟:
      Oracle提供orapwd實用程序來創建password 文件,運用orapwd建立該認證方式的具體步驟如下:
      1. 使用Orapwd實用程序來創建一個PASSWORD文件。語法:
       orapwd file=文件名 password=internal用戶密碼 entried=entries.
      詳細解釋:
       文件名要包含完整的全路徑名,如果不指定,Oracle把它默認放置$ORACLE_HOME/dbs(Unix下)或者$ORACLE_HOME/DATABASE(NT下)下。
      用戶密碼是用戶internal的密碼。當然後來還可以再向裏邊加入別的超級用戶。
      Entries表示最大允許有的超級用戶數目。這個是一個可選的。前兩者是必須指定的。一般會把它設置的比實際需要大一些,以免不夠。
      2. 把INIT.ORA中REMOTE_LOGIN_PASSWORD設置爲EXCLUSIVE 或SHARED.使用EXCLUSIVE表示只有當前INSTANCE使用這個password文件。而且允許有別的用戶作爲sysdba登錄進系統裏邊,而若選擇了SHARED,則表明不止一個實例使用這個密碼文件,伴隨着一個很強的約束:sysdba權限只能授予sys和internal這兩個用戶名。(其實internal不是一個實際用戶,而只是sys作爲sysdba登錄時的一個別名。)
      同時還要記得把sqlnet.ora文件中SQLNET.AUTHENTICATION _SERVICES設置爲NONE。一般在Unix下它是默認設置。在NT下,若選擇典型安裝時,會使用OS認證,而自定義時會使用密碼文件認證方式。在安裝過程中會提示輸入INTERNAL密碼。這樣的話,就不用在手工創建密碼文件和設定INTERNAL的密碼了。
      3. 用SQL
    Plus 或SERVER MANAGER運行下面命令登錄進系統:CONNECT INTERNAL/密碼。
      注意點:
      1.在Oracle8.1.6安裝在WIN2000下創建數據庫時,常常會發生憑證檢索失敗的錯誤。這是由於Oracle不能應用OS認證的結果。一般可以通過修改sqlnet.ora中SQLNET.AUTHENTICATION _SERVICES爲NONE來解決。這時,Oracle將採用密碼文件認證方式。
      2.由於Oracle有幾個系統預建的用戶,所以最好在安裝完成以後馬上改變這些用戶的密碼。系統默認得密碼分別爲:internal/oracle , sys/change_on_install, system/manager.
      3.當選擇密碼文件認證方式時,可以再向系統中加入其他超級用戶。比如用以下語句把用戶SCOTT加入超級用戶之中:(由具有sysdba權限的人執行)
      SQL>GRANT SYSDBA TO SCOTT;這樣SCOTT用戶就具有了sysdba權限。注意,此時SCOTT用戶可以以兩種身份登錄:SCOTT , SYS.當SCOTT在登錄時沒有輸入AS SYSDBA時,SCOTT是作爲普通用戶登錄的。而當登錄時輸入了AS SYSDBA時,此時SCOTT登錄進去的用戶實際上爲sys。
      4. 當前系統中的具有sysdba權限的用戶名可以從數據字典視圖v$pwfile_user中查詢得到:
    SELECT * FROM V$PWFILE_USERS; 如上圖所示。
      5. 系統中最大的具有sysdba權限的用戶數由創建密碼文件時的ENTRIES參數決定。當需要創建更多的具有sysdba權限的用戶時,就需要刪除原有的密碼文件,重新創建一個。這需要關閉數據庫,刪除密碼文件,重新創建一個新的密碼文件,在entries中輸入足夠大的數目。再啓動Oracle。這時,所有原來北授權的超級用戶都不再存在,需要重新授權。所以在重新創建密碼文件前,先要查詢該視圖,記下用戶名,再在創建完密碼文件後重新授權。
      6. Internal用戶密碼忘記的處理方法:
      有兩種辦法:
      1. ALTER USER SYS IDENTIFIED BY 新密碼;//這同時也改變了Internal的密碼,在Oracle8I中通過
      2. 重新創建一個新的密碼文件,指定一個新的密碼。

Oracle 添加外鍵

------------------------------摘抄-----------------------------------------

創建外鍵約束時假如使用Oracle默認的創建方式,在刪除被參照的數據時,將無法被刪除,這一點在Oracle9i中給了我們更多靈活的選擇,我們可是使用on delete cascade和 on delete set null要害字來決定刪除被參照數據時是否要將參照這個數據的那些數據一併刪除,還是將那些參照這條數據的數據的對應值賦空。

  例如下面這兩個表中分別存的時員工的基本信息和公司的部門信息。我們爲

create table dept
(deptno number(10) not null,
deptname varchar2(30) not null,
constraint pk_dept primary key(deptno));

create table emp
( empno number(10) not null,
fname varchar2(20) ,
lname varchar2(20) ,
dept number(10) ,
constraint pk_emp primary key(empno));

  然後我們現在分別使用這兩個要害字來增加外鍵試一下,首先我們來試一下on delete cascade

alter table emp
add constraint fk_emp_dept foreign key(dept) references dept(deptno) on delete cascade;

  先增加外鍵。然後插入數據。

insert into dept values(1,’銷售部’);
insert into dept values(2,’財務部’);
insert into emp values (2,’Mary’,'Song’,1);
insert into emp values (3,’Linda’,'Liu’,2);
insert into emp values (4,’Linlin’,'Zhang’,1);

  然後現在我要刪除銷售部,會有什麼後果呢?

delete from dept where deptno = 1;

  我們發現除了dept中的一條數據被刪除了,emp中兩條數據也被刪除了,其中emp中的兩條數據是參照了銷售部的這條數據的,這就很輕易理解on delete cascade了。

  接下來我們再來看on delete set null,顧名思義了,這種方式建立的外鍵約束,當被參照的數據被刪除是,參照該數據的那些數據的對應值將會變爲空值,下面我們還是通過試驗來證實on delete set null作用:

  首先恢復剛纔的那幾條數據,然後更改約束:

alter table emp
add constraint fk_emp_dept foreign key(dept) references dept(deptno) on delete set null;

  然後我們在執行刪除操作:

delete from dept where deptno = 1;

  你也會發現除了dept中的銷售部被刪除以外,emp中參照這條數據的兩條數據的dept的值被自動賦空了,這就是on delete set null的作用了。

  使用on delete set null有一點需要注重的是,被參參照其他表的那一列必須能夠被賦空,不能有not null約束,對於上面的例子來說是emp中dept列一定不能有not null約束,假如已經定義了not null約束,又使用了on delete set null來刪除被參照的數據時,將會發生:ORA-01407: 無法更新 (”DD”.”EMP”.”DEPT”) 爲 NULL的錯誤。

  總的來講on delete cascade和on delete set null的作用是用來處理級聯刪除問題的,假如你需要刪除的數據被其他數據所參照,那麼你應該決定到底希望oracle怎麼處理那些參照這些即將要刪除數據的數據的,你可以有三種方式:

  禁止刪除。這也是Oracle默認的

  將那些參照本值的數據的對應列賦空,這個需要使用on delete set null要害字

  將那些參照本值的數據一併刪除,這個需要使用on delete cascade要害字

Oracle認證考試:Oracle觸發器的語法詳解

觸發器是一種特殊的存儲過程,下面是觸發器的詳細說明:

ORACLE 觸發器

ORACLE產生數據庫觸發器的語法爲:

create [or replace] trigger 觸發器名 觸發時間 觸發事件

on 表名

[for each row]

pl/sql 語句

其中:

觸發器名:觸發器對象的名稱。由於觸發器是數據庫自動執行 的,因此該名稱只是一個名稱,沒有實質的用途。

觸發時間:指明觸發器何時執行,該值可取:

before---表示在數據庫動作之前觸發器執行;

after---表示在數據庫動作之後出發器執行。

觸發事件:指明哪些數據庫動作會觸發此觸發器:

insert:數據庫插入會觸發此觸發器;

update:數據庫修改會觸發此觸發器;

delete:數據庫刪除會觸發此觸發器。

表 名:數據庫觸發器所在的表。

for each row:對錶的每一行觸發器執行一次。如果沒有這一選項,則只對整個表執行一次。

舉例:下面的觸發器在更新表auths之前觸發,目的是不允許在週末修改表:

create trigger auth_secure

before insert or update or delete file://對整表更新前觸發

on auths

begin

if(to_char(sysdate,‘DY’)=‘SUN’

RAISE_APPLICATION_ERROR(-20600,‘不能在週末修改表auths’);

( RAISE_APPLICATION_ERROR是函數,括弧內的,第一參數範圍在-20000~20999之間,第二個

參數是字符串,大小在2k,超過的話,系統自動截斷)

end if;

end
oracle存儲過程詳解--遊標 實現增、刪、改、查的功能 收藏

        遊標(CURSOR)是ORACLE系統在內存中開闢的一個工作區,在其中存放SELECT語句返回的查詢結果.   
這個查詢結果既可以是零記錄,單條記錄,也可以是多條記錄.在遊標所定義的工作區中,存在着一個指針(POINTER),   
在初始狀態它指向查詢結果的首記錄.   

SQL是用於訪問ORACLE數據庫的語言,PL/SQL擴展和加強了SQL的功能,它同時引入了更強的程序邏輯。     

PL/SQL支持DML命令和SQL的事務控制語句。DDL在PL/SQL中不被支持,這就意味作在PL/SQL程序塊中不能創建表或其他任何對象。
較好的PL/SQL程序設計是在PL/SQL塊中使用象DBMS_SQL這樣的內建包或執行EXECUTE IMMEDIATE命令建立動態SQL來執行DDL命令,
PL/SQL編譯器保證對象引用以及用戶的權限。

  下面我們將討論各種用於訪問ORACLE數據庫的DDL和TCL語句。

  查詢

  SELECT語句用於從數據庫中查詢數據,當在PL/SQL中使用SELECT語句時,要與INTO子句一起使用,查詢的返回值被賦予INTO子句中的變量
,變量的聲明是在DELCARE中。SELECT INTO語法如下:

SELECT [DISTICT|ALL]{*|column[,column,...]}
INTO (variable[,variable,...] |record)
FROM {table|(sub-query)}[alias]
WHERE............

  PL/SQL中SELECT語句只返回一行數據。如果超過一行數據,那麼就要使用顯式遊標(對遊標的討論我們將在後面進行),
INTO子句中要有與SELECT子句中相同列數量的變量。INTO子句中也可以是記錄變量。

  %TYPE屬性

  在PL/SQL中可以將變量和常量聲明爲內建或用戶定義的數據類型,以引用一個列名,同時繼承他的數據類型和大小。
這種動態賦值方法是非常有用的,比如變量引用的列的數據類型和大小改變了,如果使用了%TYPE,那麼用戶就不必修改代碼,
否則就必須修改代碼。

 例:

v_empno SCOTT.EMP.EMPNO%TYPE;
v_salary EMP.SALARY%TYPE;

  不但列名可以使用%TYPE,而且變量、遊標、記錄,或聲明的常量都可以使用%TYPE。這對於定義相同數據類型的變量非常有用。

DELCARE
V_A NUMBER(5):=10;
V_B V_A%TYPE:=15;
V_C V_A%TYPE;
BEGIN
DBMS_OUTPUT.PUT_LINE
('V_A='||V_A||'V_B='||V_B||'V_C='||V_C);
END

SQL>/
V_A=10 V_B=15 V_C=
PL/SQL procedure successfully completed.

SQL>

  其他DML語句

  其它操作數據的DML語句是:INSERT、UPDATE、DELETE和LOCK TABLE,這些語句在PL/SQL中的語法與在SQL中的語法相同。
我們在前面已經討論過DML語句的使用這裏就不再重複了。在DML語句中可以使用任何在DECLARE部分聲明的變量,如果是嵌套塊,
那麼要注意變量的作用範圍。

  例:

CREATE OR REPLACE PROCEDURE FIRE_EMPLOYEE (pempno in number)
 AS
  v_ename EMP.ENAME%TYPE;
 BEGIN
  SELECT ename INTO v_ename
  FROM emp
  WHERE empno=p_empno;

  INSERT INTO FORMER_EMP(EMPNO,ENAME)
  VALUES (p_empno,v_ename);

  DELETE FROM emp
  WHERE empno=p_empno;

  UPDATE former_emp
  SET date_deleted=SYSDATE
  WHERE empno=p_empno;

  EXCEPTION
   WHEN NO_DATA_FOUND THEN
   DBMS_OUTPUT.PUT_LINE('Employee Number Not Found!');

 END

  DML語句的結果

  當執行一條DML語句後,DML語句的結果保存在四個遊標屬性中,這些屬性用於控制程序流程或者瞭解程序的狀態。
當運行DML語句時,PL/SQL打開一個內建遊標並處理結果,遊標是維護查詢結果的內存中的一個區域,遊標在運行DML語句時打開,完成後關閉。
隱式遊標只使用SQL%FOUND,SQL%NOTFOUND,SQL%ROWCOUNT三個屬性.SQL%FOUND,SQL%NOTFOUND是布爾值,SQL%ROWCOUNT是整數值。

  SQL%FOUND和SQL%NOTFOUND

  在執行任何DML語句前SQL%FOUND和SQL%NOTFOUND的值都是NULL,在執行DML語句後,SQL%FOUND的屬性值將是:

  . TRUE :INSERT

  . TRUE ELETE和UPDATE,至少有一行被DELETE或UPDATE.

  . TRUE :SELECT INTO至少返回一行

  當SQL%FOUND爲TRUE時,SQL%NOTFOUND爲FALSE。

  SQL%ROWCOUNT

  在執行任何DML語句之前,SQL%ROWCOUNT的值都是NULL,對於SELECT INTO語句,如果執行成功,SQL%ROWCOUNT的值爲1,如果沒有成功,
SQL%ROWCOUNT的值爲0,同時產生一個異常NO_DATA_FOUND.

  SQL%ISOPEN

  df

  事務控制語句

  事務是一個工作的邏輯單元可以包括一個或多個DML語句,事物控制幫助用戶保證數據的一致性。
如果事務控制邏輯單元中的任何一個DML語句失敗,那麼整個事務都將回滾,
在PL/SQL中用戶可以明確地使用COMMIT、ROLLBACK、SAVEPOINT以及SET TRANSACTION語句。

  COMMIT語句終止事務,永久保存數據庫的變化,同時釋放所有LOCK,ROLLBACK終止現行事務釋放所有LOCK,
但不保存數據庫的任何變化,SAVEPOINT用於設置中間點,當事務調用過多的數據庫操作時,中間點是非常有用的,
SET TRANSACTION用於設置事務屬性,比如read-write和隔離級等。

  顯式遊標

  當查詢返回結果超過一行時,就需要一個顯式遊標,此時用戶不能使用select into語句。PL/SQL管理隱式遊標,
當查詢開始時隱式遊標打開,查詢結束時隱式遊標自動關閉。顯式遊標在PL/SQL塊的聲明部分聲明,
在執行部分或異常處理部分打開,取數據,關閉。下表顯示了顯式遊標和隱式遊標的差別:
使用遊標

  這裏要做一個聲明,我們所說的遊標通常是指顯式遊標,因此從現在起沒有特別指明的情況,我們所說的遊標都是指顯式遊標。
要在程序中使用遊標,必須首先聲明遊標。

  聲明遊標

  語法:

CURSOR cursor_name IS select_statement;

  在PL/SQL中游標名是一個未聲明變量,不能給遊標名賦值或用於表達式中。

  例:

DELCARE
CURSOR C_EMP IS SELECT empno,ename,salary
FROM emp
WHERE salary>2000
ORDER BY ename;
........
BEGIN

  在遊標定義中SELECT語句中不一定非要表可以是視圖,也可以從多個表或視圖中選擇的列,甚至可以使用*來選擇所有的列 。

打開遊標

  使用遊標中的值之前應該首先打開遊標,打開遊標初始化查詢處理。打開遊標的語法是:

OPEN cursor_name

  cursor_name是在聲明部分定義的遊標名。

  例:

OPEN C_EMP;

  關閉遊標

  語法:

CLOSE cursor_name

  例:

CLOSE C_EMP;

  從遊標提取數據

  從遊標得到一行數據使用FETCH命令。每一次提取數據後,遊標都指向結果集的下一行。語法如下:

FETCH cursor_name INTO variable[,variable,...]

  對於SELECT定義的遊標的每一列,FETCH變量列表都應該有一個變量與之相對應,變量的類型也要相同。

  例:

SET SERVERIUTPUT ON
DECLARE
v_ename EMP.ENAME%TYPE;
v_salary EMP.SALARY%TYPE;
CURSOR c_emp IS SELECT ename,salary FROM emp;
BEGIN
OPEN c_emp;
FETCH c_emp INTO v_ename,v_salary;
DBMS_OUTPUT.PUT_LINE('Salary of Employee'|| v_ename
||'is'|| v_salary);
FETCH c_emp INTO v_ename,v_salary;
DBMS_OUTPUT.PUT_LINE('Salary of Employee'|| v_ename
||'is'|| v_salary);
FETCH c_emp INTO v_ename,v_salary;
DBMS_OUTPUT.PUT_LINE('Salary of Employee'|| v_ename
||'is'|| v_salary);
CLOSE c_emp;
END

  這段代碼無疑是非常麻煩的,如果有多行返回結果,可以使用循環並用遊標屬性爲結束循環的條件,以這種方式提取數據,
程序的可讀性和簡潔性都大爲提高,下面我們使用循環重新寫上面的程序:

SET SERVERIUTPUT ON
DECLARE
v_ename EMP.ENAME%TYPE;
v_salary EMP.SALARY%TYPE;
CURSOR c_emp IS SELECT ename,salary FROM emp;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp INTO v_ename,v_salary;
EXIT WHEN c_emp%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Salary of Employee'|| v_ename
||'is'|| v_salary);
END

  記錄變量

  定義一個記錄變量使用TYPE命令和%ROWTYPE,關於%ROWsTYPE的更多信息請參閱相關資料。

  記錄變量用於從遊標中提取數據行,當遊標選擇很多列的時候,那麼使用記錄比爲每列聲明一個變量要方便得多。

  當在表上使用%ROWTYPE並將從遊標中取出的值放入記錄中時,如果要選擇表中所有列,
那麼在SELECT子句中使用*比將所有列名列出來要安全得多。

  例:

SET SERVERIUTPUT ON
DECLARE
R_emp EMP%ROWTYPE;
CURSOR c_emp IS SELECT * FROM emp;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp INTO r_emp;
EXIT WHEN c_emp%NOTFOUND;
DBMS_OUT.PUT.PUT_LINE('Salary of Employee'||r_emp.ename||'is'|| r_emp.salary);
END LOOP;
CLOSE c_emp;
END;

  %ROWTYPE也可以用遊標名來定義,這樣的話就必須要首先聲明遊標:

SET SERVERIUTPUT ON
DECLARE
CURSOR c_emp IS SELECT ename,salary FROM emp;
R_emp c_emp%ROWTYPE;
BEGIN
OPEN c_emp;
LOOP
FETCH c_emp INTO r_emp;
EXIT WHEN c_emp%NOTFOUND;
DBMS_OUT.PUT.PUT_LINE('Salary of Employee'||r_emp.ename||'is'|| r_emp.salary);
END LOOP;
CLOSE c_emp;
END;

  帶參數的遊標

  與存儲過程和函數相似,可以將參數傳遞給遊標並在查詢中使用。這對於處理在某種條件下打開遊標的情況非常有用。它的語法如下:

CURSOR cursor_name[(parameter[,parameter],...)] IS select_statement;

  定義參數的語法如下:

Parameter_name [IN] data_type[{:=|DEFAULT} value]

  與存儲過程不同的是,遊標只能接受傳遞的值,而不能返回值。參數只定義數據類型,沒有大小。

  另外可以給參數設定一個缺省值,當沒有參數值傳遞給遊標時,就使用缺省值。遊標中定義的參數只是一個佔位符,
在別處引用該參數不一定可靠。

  在打開遊標時給參數賦值,語法如下:

OPEN cursor_name[value[,value]....];

  參數值可以是文字或變量。

  例:

DECALRE

CURSOR c_dept IS SELECT * FROM dept ORDER BY deptno;
CURSOR c_emp (p_dept VARACHAR2) IS
SELECT ename,salary
FROM emp
WHERE deptno=p_dept
ORDER BY ename
r_dept DEPT%ROWTYPE;
v_ename EMP.ENAME%TYPE;
v_salary EMP.SALARY%TYPE;
v_tot_salary EMP.SALARY%TYPE;

BEGIN

OPEN c_dept;
LOOP
FETCH c_dept INTO r_dept;
EXIT WHEN c_dept%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Department:'|| r_dept.deptno||'-'||r_dept.dname);
v_tot_salary:=0;
OPEN c_emp(r_dept.deptno);
LOOP
FETCH c_emp INTO v_ename,v_salary;
EXIT WHEN c_emp%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Name:'|| v_ename||' salary:'||v_salary);
v_tot_salary:=v_tot_salary+v_salary;
END LOOP;
CLOSE c_emp;
DBMS_OUTPUT.PUT_LINE('Toltal Salary for dept:'|| v_tot_salary);
END LOOP;
CLOSE c_dept;
END;
遊標FOR循環

  在大多數時候我們在設計程序的時候都遵循下面的步驟:

  1、打開遊標

  2、開始循環

  3、從遊標中取值

  4、檢查那一行被返回

  5、處理

  6、關閉循環

  7、關閉遊標

  可以簡單的把這一類代碼稱爲遊標用於循環。但還有一種循環與這種類型不相同,這就是FOR循環,
用於FOR循環的遊標按照正常的聲明方式聲明,它的優點在於不需要顯式的打開、關閉、取數據,測試數據的存在、定義存放數據的變量等等
。遊標FOR 循環的語法如下:

FOR record_name IN
(corsor_name[(parameter[,parameter]...)]
| (query_difinition)
LOOP
statements
END LOOP;

  下面我們用for循環重寫上面的例子:

DECALRE

CURSOR c_dept IS SELECT deptno,dname FROM dept ORDER BY deptno;
CURSOR c_emp (p_dept VARACHAR2) IS
SELECT ename,salary
FROM emp
WHERE deptno=p_dept
ORDER BY ename

v_tot_salary EMP.SALARY%TYPE;

BEGIN

FOR r_dept IN c_dept LOOP
DBMS_OUTPUT.PUT_LINE('Department:'|| r_dept.deptno||'-'||r_dept.dname);
v_tot_salary:=0;
FOR r_emp IN c_emp(r_dept.deptno) LOOP
DBMS_OUTPUT.PUT_LINE('Name:'|| v_ename||' salary:'||v_salary);
v_tot_salary:=v_tot_salary+v_salary;
END LOOP;
DBMS_OUTPUT.PUT_LINE('Toltal Salary for dept:'|| v_tot_salary);
END LOOP;

END;

  在遊標FOR循環中使用查詢

  在遊標FOR循環中可以定義查詢,由於沒有顯式聲明所以遊標沒有名字,記錄名通過遊標查詢來定義。

DECALRE

 v_tot_salary EMP.SALARY%TYPE;

BEGIN

 FOR r_dept IN (SELECT deptno,dname FROM dept ORDER BY deptno) LOOP
  DBMS_OUTPUT.PUT_LINE('Department:'|| r_dept.deptno||'-'||r_dept.dname);
  v_tot_salary:=0;
  FOR r_emp IN (SELECT ename,salary
   FROM emp
   WHERE deptno=p_dept
   ORDER BY ename) LOOP
  DBMS_OUTPUT.PUT_LINE('Name:'|| v_ename||' salary:'||v_salary);
  v_tot_salary:=v_tot_salary+v_salary;
  END LOOP;
  DBMS_OUTPUT.PUT_LINE('Toltal Salary for dept:'|| v_tot_salary);
 END LOOP;

END;

  遊標中的子查詢

  語法如下:

CURSOR C1 IS SELECT * FROM emp
WHERE deptno NOT IN (SELECT deptno
FROM dept
WHERE dname!='ACCOUNTING');

  可以看出與SQL中的子查詢沒有什麼區別。

  遊標中的更新和刪除**POINT

  在PL/SQL中依然可以使用UPDATE和DELETE語句更新或刪除數據行。顯式遊標只有在需要獲得多行數據的情況下使用。
PL/SQL提供了僅僅使用遊標就可以執行刪除或更新記錄的方法。

  UPDATE或DELETE語句中的WHERE CURRENT OF子串專門處理要執行UPDATE或DELETE操作的表中取出的最近的數據。
要使用這個方法,在聲明遊標時必須使用FOR UPDATE子串,當對話使用FOR UPDATE子串打開一個遊標時,
所有返回集中的數據行都將處於行級(ROW-LEVEL)獨佔式鎖定,其他對象只能查詢這些數據行,
不能進行UPDATE、DELETE或SELECT...FOR UPDATE操作。

  語法:

FOR UPDATE [OF [schema.]table.column[,[schema.]table.column]..
[nowait]

  在多表查詢中,使用OF子句來鎖定特定的表,如果忽略了OF子句,那麼所有表中選擇的數據行都將被鎖定。
如果這些數據行已經被其他會話鎖定,那麼正常情況下ORACLE將等待,直到數據行解鎖。

  在UPDATE和DELETE中使用WHERE CURRENT OF子串的語法如下:

WHERE{CURRENT OF cursor_name|search_condition}

  例:

DELCARE

CURSOR c1 IS SELECT empno,salary
FROM emp
WHERE comm IS NULL
FOR UPDATE OF comm;

v_comm NUMBER(10,2);

BEGIN

FOR r1 IN c1 LOOP

IF r1.salary<500 THEN
v_comm:=r1.salary0.25;
ELSEIF r1.salary<1000 THEN
v_comm:=r1.salary
0.20;
ELSEIF r1.salary<3000 THEN
v_comm:=r1.salary0.15;
ELSE
v_comm:=r1.salary
0.12;
END IF;

UPDATE emp;
SET comm=v_comm
WHERE CURRENT OF c1l;

END LOOP;
END

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章