Oracle筆試題庫 附參考答案


1.  下列不屬於ORACLE的邏輯結構的是(C)

  1. 數據文件
  2. 表空間

 

2. 下面哪個用戶不是ORACLE缺省安裝后就存在的用戶(A)

A . SYSDBA

B. SYSTEM

C. SCOTT

D. SYS

 

3         下面哪個操作會導致用戶連接到ORACLE數據庫,但不能創建表(A)

  1. 授予了CONNECT的角色,但沒有授予RESOURCE的角色
  2. 沒有授予用戶系統管理員的角色
  3. 數據庫實例沒有啟動
  4. 數據庫監聽沒有啟動

 

  1. ( )函數通常用來計算累計排名,移動平均數和報表聚合。

A . 匯總

B. 分析

C 分組、

D 單行

 

  1. 帶有(B)字句的SELECT語句可以在表的一行或多行放置排他鎖。

A .  FOR INSERT

B.  FOR UPDATE

C.  FOR DELETE

D.  FOR REFRESH

 

  1. 在Oracle中,你以SYSDBA登錄,CUSTOMER表位於Mary用戶方案中,下面哪條語句為數據庫中的所有用戶創建CUSTOMER表的同義詞(B)。
    1. CREATE PUBLIC SYNONYM cust ON mary.customer;
    2. CREATE PUBLIC SYNONYM cust FOR mary.customer;
    3. CREATE SYNONYM cust ON mary.customer FOR PUBLIC;
    4. 不能創建CUSTOMER的公用同義詞。

7. 在Oracle中,當FETCH語句從游標獲得數據時,下面敘述正確的是(C)。

  1. 游標打開
  2. 游標關閉
  3. 當前記錄的數據加載到變量中
  4. 創建變量保存當前記錄的數據

8. 在Oracle中,下面關於函數描述正確的是(AD)。

  1. SYSDATE函數返回Oracle服務器的日期和時間
  2. ROUND數字函數按四舍五入原則返回指定十進制數最靠近的整數
  3. ADD_MONTHS日期函數返回指定兩個月份天數的和
  4. SUBSTR函數從字符串指定的位置返回指定長度的子串

 

 

9. 閱讀下面的PL/SQL程序塊:

BEGIN

INSERT INTO employee(salary,last_name,first_name)

VALUES(35000,’Wang’,'Fred’);

SAVEPOINT save_a;

INSERT INTO employee(salary,last_name,first_name)

VALUES(40000,’Woo’,'David’);

SAVEPOINT save_b;

DELETE FROM employee WHERE dept_no=10;

SAVEPOINT save_c;

INSERT INTO employee(salary,last_name,first_name)

VALUES(25000,’Lee’,'Bert’);

ROLLBACK TO SAVEPOINT save_c;

INSERT INTO employee(salary,last_name,first_name)

VALUES(32000,’Chung’,'Mike’);

ROLLBACK TO SAVEPOINT save_b;

COMMIT;

END;

運行上面的程序,哪兩個更改永久保存到數據庫(CD)。

  1. DELETE FROM employee WHERE dept_no=10;
  2. INSERT INTO employee(salary,last_name,first_name)
    1.                         i.              VALUES(32000,’Chung’,'Mike’);
    2. INSERT INTO employee(salary,last_name,first_name)
      1.                         i.              VALUES(35000,’Wang’,'Fred’);
      2. INSERT INTO employee(salary,last_name,first_name)
        1.                         i.              VALUES(40000,’Woo’,'David’);

 

 

10. 在Oracle中,表VENDOR包含以下列:

VENDOR_ID NUMBER Primary Key

NAME VARCHAR2(30)

LOCATION_ID NUMBER

ORDER_DT DATE

ORDER_AMOUNT NUMBER(8,2)

下面對表VENDOR運用分組函數的子句合法的是(C)。

  1. FROM MAX(order_dt)
  2. SELECT SUM(order_dt)
  3. SELECT SUM(order_amount)
  4. WHERE MAX(order_dt) = order_d

 

11. 在Oracle中,表EMP包含以下列:

……

NAME VARCHAR2(20)

ADDR VARCHAR2(60)

……

要以NAME’s address is ADDR格式返回數據,以下SQL語句正確的是(B)。

+ 的兩邊做To_number()

  1. SELECT NAME + ’’’s address is ‘ + ADDR FROM EMP;
  2. SELECT NAME || ’’’s address is ‘ || ADDR FROM EMP;
  3. SELECT NAME + ’\’s address is ‘ + ADDR FROM EMP;
  4. SELECT NAME || ’\’s address is ‘ || ADDR FROM EMP;

 

 

12. 在Oracle中,以下不屬於集合操作符的是(B)。

  1. UNION
  2. SUM
  3. MINUS
  4. INTERSECT

 

13. 在Oracle中,表分區方式(C)建議分區數是2的冪(2、4、8等),以獲得最平均的數據發布。

  1. 范圍分區
  2. 列表分區
  3. 散列分區
  4. 復合分區

 

14. 在Oracle中,關於鎖,下列描述不正確的是(D)。

  1. 鎖用於在用戶之間控制對數據的並發訪問
  2. 可以將鎖歸類為行級鎖和表級鎖
  3. insert、update、delete語句自動獲得行級鎖
  4. 同一時間只能有一個用戶鎖定一個特定的表

 

15 .在Oracle中,關於表分區下列描述不正確的是()。

  1. 分區允許對選定的分區執行維護操作,而其他分區對於用戶仍然可用
  2. 不可以對包含LONG或LONG RAW列的表進行分區
  3. 不可以對包含任何LOB列的表進行分區
  4. 如果分區鍵包含DATE數據類型的列,則必須使用TO_DATE函數完整的指定年份

 

 

 

16:

在Oracl中,哪種表分區維護操作可以將非分區表轉換為分區表的分區()。

  1. 添加分區
  2. 結合分區
  3. 交換表分區
  4. 合並分區

 

 

17:

在Oracle中,使用帶有()子句的SELECT命令可以在表的一行或多行上放置排他鎖。

  1. FOR INSERT OF
  2. FOR REFRESH
  3. FOR UPDATE OF
  4. FOR LOCK

 

 

18:

在Oracle中,序列venseq使用下面的語句創建:

CREATE SEQUENCE venseq INCREMENT BY 1 START WITH 10

MAXVALUE 100 MINVALUE 10 CYCLE CACHE 5;

下面對序列venseq修改的語句,錯誤的是(A)。

  1. ALTER SEQUENCE venseq START WITH 1;
  2. ALTER SEQUENCE venseq MAXVALUE 90;
  3. ALTER SEQUENCE venseq NOMINVALUE;
  4. ALTER SEQUENCE venseq NOCACHE;

19:

在Oracle中,使用以下語句創建視圖:

CREATE OR REPLACE VIEW pen_view

AS SELECT * FROM order_master

WHERE ostatus = ‘p’ WITH CHECK OPTION CONSTRAINT penv;

當用戶試圖執行以下語句:

UPDATE pen_view SET ostatus = ‘d’ WHERE ostatus=’p’;

下列描述正確的是(B)。

  1. Oracle將ostatus修改為d,不提示任何錯誤
  2. Oracle不執行更新操作,並返回錯誤信息
  3. Oracle將ostatus修改為d,同時返回錯誤信息
  4. Oracle不執行更新操作,也不提示任何錯誤

20:

在Oracle中,在以下情形建立位圖索引可以獲得較好的性能(C)。

  1. 在列值唯一的列上建立
  2. 在列值相差很小的列上建立
  3. 在列值頻繁重復的列上建立
  4. 在用於保存位圖的列上建立

21:

在Oracle中,通過命令(C)可以釋放鎖。

  1. INSERT
  2. DELETE
  3. ROLLBACK
  4. UNLOCK

22

在Oracle中,下面關於簇的描述不正確的是(B)。

  1. 簇是一組表,這些表擁有公共列,並且經常一起使用
  2. 與每個表及其索引單獨存儲相比,簇能夠提高INSERT語句的性能
  3. 由於簇表中的所有行都使用相同的列作為公共主鍵,因此這些列僅為所有表存儲一次,從而節省了存儲空間
  4. 經常更新的列不應選作簇鍵

23:

在Oracle中,抽象數據類型address_ty定義如下:

CREATE TYPE address_ty AS OBJECT

( street_no number(3),

street_name varchar2(20),

city varchar2(20),

state varchar2(20))

/

表vend_mast定義如下:

CREATE TABLE vend_mast

(vencode varchar2(5), venname varchar2(15),

venadd address_ty, tel_no number(10));

下列語句能正確執行的是()。

  1. SELECT city FROM vend_mast WHERE venname=’Joe’;
  2. UPDATE vend_mast SET address_ty.street_no=10

WHERE venname=’john’;

  1. DELETE FROM vend_mast a WHERE a.venadd.vencode=’v100’;   需要啟別名才能訪問
  2. SELECT a.venadd.street_name FROM vend_mast a

WHERE street_no=11;

 

 

24:

在Oracle中,()數據字典表可以用來查看抽象數據類型的實際結構。

  1. USER_TYPE_ATTRS
  2. USER_TABLES
  3. USER_TYPE_TABS
  4. USER_TAB_COLUMNS

 

25:

在Oracle中,(B)操作符允許引用現有的行對象。

  1. CAST
  2. REF
  3. MULTISET
  4. MAP

26:

在Oracle中,關於PL/SQL下列描述正確的是(C)。

  1. PL/SQL代表Power Language/SQL
  2. PL/SQL不支持面向對象編程
  3. PL/SQL塊包括聲明部分、可執行部分和異常處理部分
  4. PL/SQL提供的四種內置數據類型是character,integer,float,boolean

27:

在Oracle中,閱讀下列PL/SQL塊:

DECLARE

v_lower NUMBER:=2;

v_upper NUMBER:=100;

v_count NUMBER:=1;

BEGIN

I = 2; I <= 2; i++

FOR i IN v_lower..v_lowerLOOP

INSERT INTO test(results)

VALUES (v_count);

v_count := v_count +1;

ENDLOOP;

END;

請問FOR LOOP循環體執行了(A)次。

  1. 1
  2. 2
  3. 98
  4. 100
  5. 235:

28:

在Oracle中,()程序包中提供了所有預定義的異常的定義。

  1. DBMS_STANDARD
  2. DBMS_STD
  3. DBMS_SQL
  4. DBMS_TYPES

 

 

29:

在Oracle中,關於子程序的描述不正確的是(C)。

子程序 就是存儲過程和函數

  1. 子程序是已命名的PL/SQL塊,可帶參數並可在需要時隨時調用
  2. 子程序可以具有聲明部分、可執行部分和異常處理部分
  3. 子程序參數的模式只有IN和OUT兩種模式
  4. 子程序可分為過程和函數兩種類型

 

 

30:

在Oracle中,當從SQL表達式調用函數時,下列描述不正確的是(AC)。

  1. 從SELECT語句調用的函數均不能修改數據庫表
  2. 函數可以帶有IN、OUT等模式的參數
  3. 函數的返回值必須是數據庫類型,不得使用PL/SQL類型
  4. 形式參數必須使用數據庫類型,不得使用PL/SQL類型

31:

在Oracle中,關於觸發器的描述正確的是(D)。

  1. 觸發器可以刪除,但不能禁用
  2. 觸發器只能用於表
  3. 觸發器可以分為行級和語句級兩種
  4. 觸發器是一個對關聯表發出insert、update、delete或select … for update語句時觸發的存儲過程

32:

在Oracle中,你需要創建索引提高薪水審查的性能,該審查要對員工薪水提高12個百分點后進行分析處理,下面哪個create index命令能解決此問題(A)。

  1. CREATE INDEX my_idx_1 ON employee(salary*1.12);
  2. CREATE UNIQUE INDEX my_idx_1 ON employee(salary);
  3. CREATE BITMAP INDEX my_idx_1 ON employee(salary);
  4. CREATE INDEX my_idx_1 ON employee(salary) REVERSE;

 

 

33:

在Oracle中,執行下面的語句:

SELECT ceil(-97.342),

floor(-97.342),  -123.01 -124

round(-97.342),

trunc(-97.342)

FROM dual;

 

哪個函數的返回值不等於-97(B)。

  1. ceil()
  2. floor()
  3. round(0)
  4. trunc()

34:

在Oracle中,用以下SQL命令創建了一個序列:

CREATE SEQUENCE my_seq

START WITH 394

INCREMENT BY 12

NOMINVALUE

NOMAXVALUE

NOCYCLE

NOCACHE;

用戶執行包含my_seq.NEXTVAL的SQL語句三次,然后執行包含(seq建好后的第一次my_seq.NEXTVAL值不增加還是394)

my_seq.CURRVAL的SQL語句四次,請問序列my_seq的當前值是(B)。

  1. 406
  2. 418
  3. 430
  4. 442
  5. 242:

 

35:

在Oracle中,下列哪種標量類型不能保存到數據庫表中(B)。

  1. CHAR
  2. RAW
  3. DATE
  4. BOOLEAN

36:

在Oracle中,不屬於游標屬性的是(C)。

  1. %NOTFOUND
  2. %FOUND
  3. %ISCLOSE
  4. %ISOPEN

37:

在Oracle中,在SQL提示符下調用PL/SQL過程的方法是(ABC)。

  1. 使用CALL語句
  2. 使用EXECUTE語句
  3. 使用RUN語句
  4. 直接使用過程名

38:

在Oracle中,用下列語句定義了一個過程:

CREATE OR REPLACE PROCEDURE test(a IN VARCHAR2,

b IN OUT NUMBER,

c OUT VARCHAR2) IS

BEGIN

……

END;

/

假定使用的變量都已定義,下面對過程test的調用語法正確的是(C)。

  1. test(‘String1’,50,v_str2)
  2. test(v_str1,v_num1,’String2’)
  3. test(‘String1’,v_num1,v_str2)
  4. test(v_str1,20,v_str2)

39:

在Oracle中,關於程序包的描述不正確的是(B)。

  1. 程序包是一種數據庫對象,它是對相關PL/SQL類型、子程序、游標、異常、變量和常量的封裝
  2. 程序包中私有對象是通過PRIVATE關鍵字來標識的  程序包體可以包括沒有在程序包說明中列出的對象,這些是私有對象,程序包的用戶不能使用
  3. PL/SQL允許兩個或多個打包的子程序具有同一名稱,只要子程序接受的參數數據類型不同
  4. 程序包具有模塊化、信息隱藏、新增功能及性能更佳等優點

40:

在Oracle中,用戶(A)擁有所有內置的程序包。

  1. SYS
  2. SYSTEM
  3. PUBLIC
  4. DEFAULT

 

 

41:

在Oracle中,DBMS_LOB程序包的()過程用於刪除指定的BLOB或CLOB。

  1. delete
  2. erase
  3. remove
  4. empty_lob

 

 

42

在Oracle中,關於觸發器的描述正確的是(D)。(選擇一項)

  1. 觸發器可以刪除,但不能禁用
  2. 觸發器只能用於表
  3. 觸發器可以分為行級和語句級
  4. 觸發器使一個對關聯表發出select、insert、update或delete語句時觸發的存儲過程

 

 

43:

在Oracle中,通過命令(CD)可以釋放鎖。(選擇兩項)

  1. INSERT
  2. DELETE
  3. ROLLBACK
  4. COMMIT

44:

在Oracle中,事務中使用下列SQL語句不會引起鎖定(A)。(選擇一項)

  1. SELECT
  2. INSERT
  3. UPDATE
  4. DELETE

45:

在Oracle中,當需要使用顯式游標更新或刪除游標中的行時,聲明游標時指定的SELECT語句必須帶有(C)子句。(選擇一項)

  1. WHERE CURRENT OF
  2. INTO
  3. FOR UPDATE
  4. ORDER BY

46:

在Windows操作系統中,Oracle的(A)服務器監聽並接受來自客戶端應用程序的連接請求。(選擇一項)

  1. OracleHOME_NAMETNSListener
  2. OracleServiceSID
  3. OracleHOME_NAMEAgent
  4. OracleHOME_NAMEHTTPServer

47:

在Oracle中,有一個名為seq的序列對象,以下語句能返回序列值但不會引起序列值增加的是(C)。(選擇一項)

  1. select seq.ROWNUM from dual;
  2. select seq.ROWIDfrom dual;
  3. select seq.CURRVALfrom dual;
  4. select seq.NEXTVALfrom dual;

48:

ORACLE中,執行語句:SELECT address1||’,'||address2||’,'||address2   ”Address” FROM employ;將會返回(B)列。

  1. 0
  2. 1
  3. 2
  4. 3

49:

在Oracle中,INSTEAD OF觸發器主要用於(D)。(選擇一項)

  1. 表和視圖
  2. 基於單個表的視圖
  3. 基於多個表的視圖

 

50:

Oracle數據庫中,下面(C)可以作為有效的列名。

  1. Column
  2. 123_NUM
  3. NUM_#123
  4. #NUM123

51:

在Oracle中,以下工具可以邏輯備份數據庫對象或整個數據庫(B)。(選擇一項)

  1. SQL*Plus
  2. 導出實用程序
  3. 導入實用程序
  4. SQL*Loader

52:

Oracle數據庫中,通過(B)訪問能夠以最快的方式訪問表中的一行。

  1. 主鍵
  2. Rowid
  3. 唯一索引
  4. 整表掃描

 

53:

在Oracle中,使用下列的語句產生序列:

CREATE SEQUENCE id;

Oracle服務器會預開辟內存並維持的序列值有(C)個。(選擇一項)

  1. 0
  2. 10
  3. 20
  4. 100

 

54:

Oracle數據庫中,以下(C)命令可以刪除整個表中的數據,並且無法回滾。

  1. drop
  2. delete
  3. truncate
  4. cascade

 

 

55:

Oralce數據庫中,以下(A)函數可以針對任意數據類型進行操作。

  1. TO_CHAR
  2. LOWER
  3. MAX
  4. CEIL

56:

在Oracle中,語句(B)將ORDER_DATE日期值’2000年3月18日’顯示為‘2000年1月1日’。(選擇一項)

  1. SELECT ROUND(order_date,’day’)FROM inventory
  2. SELECT ROUND(order_date,’YEAR’)FROM inventory
  3. SELECT ROUND(order_date,’month’)FROM inventory
  4. SELECT ROUND(to_char(order_date,’yyyy’))FROM inventory

57:

在Oracle中,以下是STUDENTS表的結構:

SID NUMBER NOT NULL,Primary Key

SNAME VARCHAR2(30)

COURSE_ID VARCHAR2(10) NOT NULL

MARKS NUMBER

你需要查詢參加了課程ID為C10的考試,並且分數排在前10名的學生,以下(D)語句能夠實現此功能。

A. SELECT SID,marks,ROWNUM “Rank”

FORM students

WHERE ROWNUM<=10 AND course_id=’C10′

ORDER BY marks DESC;

 

B.SELECT SID,marks,ROWNUM”Rank”

FORM students

WHERE ROWNUM<=10 AND course_id=’C10′

ORDER BY marks;

C.

SELECT SID,marks,ROWNUM”Rank”

FORM (SELECT SID ,marks

FORM students

WHERE ROWNUM<=10 AND course_id=’C10′

ORDER BY marks DESC;

D.

SELECT SID,marks,ROWNUM”Rank”

FORM (SELECT SID ,marks

FORM students

WHERE course_id=’C10′ ORDER BY marks DESC)

WHERE ROWNUM<=10;

 

58:

在Oracle中,用下列語句定義一個過程:

CREATE PROCEDURE proc(value1 in varchar2,value2 out number,value3 in out varchar2)

is

begin

……

end;

假定使用的變量都已定義,下面對過程proc的調用語法正確的是().(選擇一項)

  1. proc(‘tt’,10,v3)
  2. proc(‘tt’,v2,v3)
  3. proc(v1,v2,v3)
  4. proc(‘tt’,10,’dd’)

 

59:

在Oracle中,使用以下語句創建視圖;

create or replace view myView

as select * from orders

where status=’p';

假定Orders表中包含10條status=’p'的記錄,當用戶試圖執行以下語句;

update myView set status=’o’ where status=’p';

下列正確的是()

  1. Oracle不執行更新操作,並返回錯誤信息
  2. Oracle成功執行更新操作,再次查看視圖時返回0行記錄
  3. Oracle成功執行更新操作,再次查看視圖時返回10行記錄
  4. Oracle執行更新操作,但提示錯誤信息

60:

在Oracle中,用於PL/SQL程序輸出調試信息的內置程序包是D

  1. DBMS_STANDARD
  2. DBMS_ALERT
  3. DBMS_LOB
  4. DBMS_OUTPUT

 

61:

在Oracle中,用下列語句定義了一個過程:

CREATE PROCEDURE proc(value1 IN VARCHAR2,value2 OUT NUMBER,value3 IN OUT VARCHAR2)

IS

BEGIN

……

END;

假定使用的變量都已定義,下面對過程proc的調用語法正確的是(B)。

  1. proc(‘tt’,10,v3)
  2. proc(‘tt’,v2,v3)
  3. proc(v1,v2,v3)
  4. proc(‘tt’,10,’dd’)

62:

在Oracle中,使用以下語句創建視圖:C

CREATE OR REPLACE VIEW MyView

AS SELECT * FROM orders

Where status=’p';

假定orders表中包含10條status=’p'的記錄,當用戶試圖執行以下語句:

UPDATE MyView SET status=’o’ WHERE status=’p';

下列描述正確的是()。

  1. Oracle不執行更新操作,並返回錯誤信息
  2. Oracle成功執行更新操作,再次查看視圖時返回0行記錄
  3. Oracle成功執行更新操作,再次查看視圖時返回10行記錄
  4. Oracle執行更新操作,但提示錯誤信息

63:

在Oracle中,語句()將ORDER_DATE日期值’2000年3月18日’顯示為’2000年1月1日’(選擇兩項)

  1. select round(order_date,’day’)from inventory
  2. select round(order_date,’year’)from inventory
  3. select round(order_date,’month’)from inventory
  4. select round(to_char(order_date,’yyyy’))from inventory

64:

在Oracle中,使用下列語句產生序列:

CREATE SEQUENCE id;

Oracle服務器會預開辟內存並維持的序列值有()個(選擇一項)

  1. 0
  2. 10
  3. 20
  4. 100
  5. 292:

65:

在Oracle中,以下工具可以邏輯備份數據庫對象或整個數據庫().

  1. sql*plus
  2. 導出實用程序
  3. 導入實用程序
  4. sql*loader

66:

在Oracle中,INSTEAD OF觸發器主要用於()

  1. 表和視力圖
  2. 基於單個表的視圖
  3. 基於多個表的視圖

67:

在Oracle中,用於顯示PL/SQL程序輸出調試信息的內置程序包是()。

  1. DBMS_STANDARD
  2. DBMS_ALERT
  3. DBMS_LOB
  4. DBMS_OUTPUT

68:

在Oracle中,有一個名為seq的序列對象,以下語句能返回序列值但不會引起序列值增加的是()。

  1. select seq.ROWNUM form dual;
  2. select seq.ROWID form dual;
  3. select seq.CURRVAL form dual;
  4. select seq.NEXTVAL form dual;

69:

在Oracle中,事務中使用下列SQL語句不會引起鎖定()。

  1. SELECT
  2. INSERT
  3. UPDATE
  4. DELETE

 

70.

在Oracle中,通過命令()可以釋放鎖。

  1. INSERT
  2. DELETE
  3. ROLLBACK
  4. COMMIT

71

在Oracle中,關於觸發器的描述正確的是()。

  1. 觸發器可以刪除,但不能禁用
  2. 觸發器只能用於表
  3. 觸發器可以分為行級和語句級
  4. 觸發器是一個對關聯表發出select、insert、update或delete語句是觸發的存儲過程

72:

ORACLE 中,執行語句: SELECT address1||’,’||address2||’,’||address2  “Adress” FROM employ;將會返回()列。(選擇一項)

  1. 0
  2. 1
  3. 2
  4. 3

73:

在Oracle中,PL/SQL塊中定義了一個帶參數的游標:

CURSOR emp_cursor(dnum NUMBER) IS

SELECT sal,comm FORM emp WHERE deptno=dnum;

那么正確打開此游標的語句是(AD)。

  1. OPEN emp_cursor(20);
  2. OPEN emp_cursor FOR 20;
  3. OPEN emp_cursor USING 20;
  4. FOR rmp_rec IN emp_cursor(20) LOOP … ENDLOOP;

74:

Oracle數據庫中,下面()可以作為有效的列名。(選擇一項)

  1. 75: Column
  2. 123_NUM
  3. NUM_#123
  4. #NUM123

 

Oracle數據庫中,通過(B)訪問能夠以最快的方式訪問表中的一行。(選擇一項)

  1. 主鍵
  2. Rowid
  3. 唯一索引
  4. 整表掃描

76:

Oracle數據庫中,以下()函數可以針對任意數據類型進行操作。

  1. TO_CHAR
  2. LOWER
  3. MAX
  4. CEIL

77:

Oracle數據庫中,以下()命令可以刪除整個表中的數據,並且無法回滾。(選擇一項)

  1. drop
  2. delete
  3. truncate
  4. cascade

78:

在Oracle中,下列(B)語句不能用於控制游標。

  1. Open
  2. Create
  3. Fetch
  4. Close

79:

在Oracle中有表”cd”,它包含屬性”cdcode”,”category”和”cdname”,要查詢category取值為”CLASSIC”或”ROCK”的行,應采用語句(AD)。

  1. SELECT * FROM cd WHERE category IN (‘CLASEIC’,'ROCK’);
  2. SELECT * FROM cd WHERE category BETWEEN ‘CLASSIC’ AND ‘ROCK’;
  3. SELECT * FROM cd WHERE category=’CLASSIC’ AND category=’ROCK’;
  4. SELECT * FROM cd WHERE category=’CLASSIC’ OR category=’ROCK’;

80:

在Oracle中,在執行SQL語句時,你不小心使用Update命令將所有的ID值設置成了11111,那么使用(C)命令可以取消這一操作。

  1. EXIT
  2. COMMIT
  3. ROLLBACK
  4. UNDO

81

在Oracle中,數據庫中的觸發器是一個對關聯表發出insert、update或(A)語句時觸發的存儲過程。(選擇一項)

A     delete

B     drop

C     create

D     truncate

 

82

在Oracle 中,使用了如下的語句創建用戶TOM,則對於該用戶而言,以下說法錯誤的是(D)。(選擇一項)CREATE USER TOM IDENTIFIED BY TOMSYS

A     該用戶的口令為TOMSYS

B     TOM默認為表空間為SYSTEM

C     TOM 的臨時表空間為TEMP

D     使ORANT UPDATE 命令可以修改TOM的口令

 

83

在Oracle中,下述(A)命令會使掛起的事務完成。(選擇一項)。(選擇一項)

A     COMMIT

B     DELETE

C     UPDATE

D     SELECT

e)    INSERT

84

游標變量的類型是(B )

A     隱式游標

B     顯示游標

C     REF游標

D     循環游標

 

85

在非歸檔方式下操作的數據庫禁用了(A)。(選擇一項)

A     歸檔日志。

B     聯機日志。

C     日志寫入程序。

D     日志文件。

 

86

由於軟硬件問題導致的讀寫數據庫文件失敗,屬於(D)故障。(選擇一項)

A     實例

B     語句

C     用戶進程

D     介質

 

87

(C )參數用於確定是否要導入整個導出文件

A     constranints

B     tables

C     full

D     file

 

88

在oracle程序中處理語句時發生的邏輯錯誤導致(C )故障

A     實例

B     介質

C     語句

D     用戶進程

 

89

以下哪種備份方式需要在完全關閉數據庫后進行。

A     無歸檔日志模式。

B     歸檔日志模式。

C     使用導出實用程序進行邏輯備份。

D     以上都不對。

90

(B)方式的導出會從指定的表中導出所有的數據。(選擇一項)

A     分區

B     表

C     全部數據庫

D     表空間

91

使用(B)命令可查看在創建觸發器時發生的編譯錯誤

A     View errors

B     Show errors

C     Display errors

D     Check errors

 

92

(A)包用於顯示pl/sql塊和存儲過程中的調試信息

A     Dbms_output。

B     Dbms_standadr。

C     Dbms_Input。

D     Dbms_session。

 

93

(A)觸發器允許觸發操作的語句訪問行的列值

A     行級 :old :new

B     語句級

C     模式

D     數據庫級

 

94

要審計用戶執行的create,drop,和alter等ddl語句,應創建(E )觸發器

A     行級

B     語句級

C     Instead of

D     模式

e)    數據庫

 

95

Oracle內置程序包由(A )用戶所有

A     sys

B     system

C     scott

D     Pub lic

 

96

( D)程序包用於讀寫操作系統文本文件

A     Dbms_output

B     Dbms_lob (圖片,電影)

C     Dbms_random

D     Utl_file

97

以下不屬於命令的pl/sql塊的是( )

A     程序包

B     過程。

C     游標。

D     函數

 

 

98

執行特定任務的子程序是( AB)

A     函數

B     過程。

C     程序包

D     游標。

 

99

子程序的(A )模式參數可以在調用子程序時指定一個常量

A     in

B     out

C     In out

D     inout

 

100

下面關於主事務處理和自主事務處理的說法錯誤的是( D)

A     自主事務處理結果的變化不倚賴於主事務處理的狀態

B     自主事務處理提交或回退時,不影響主事務處理的結果

C     自主事務處理提交,對主事務處理是不可見的

D     自主事務處理還可以啟動其他自主事務處理

 

Create   proc p1

Begin

Insert …..

P2();

Update ….

Commit;

End;

 

Create proc p2

Begin

Atuo………

Inusert….

Rollback;

End;

 

 

用 JDBC 查詢學生成績單, 把主要代碼寫出來(考試概率極大).
Connection cn = null;
PreparedStatement pstmt =null;
Resultset rs = null;
try
{
	Class.forname(driveClassName);
	cn =  DriverManager.getConnection(url,username,password);
	pstmt = cn.prepareStatement(“select  score.* from score ,student “ +
		“where score.stuId = student.id and student.name = ?”);
	pstmt.setString(1,studentName);
	Resultset rs = pstmt.executeQuery();
	while(rs.next())
	{
		system.out.println(rs.getInt(“subject”)  +  “    ” + rs.getFloat(“score”) );
	}
}catch(Exception e){e.printStackTrace();}
finally
{
	if(rs != null) try{ rs.close() }catch(exception e){}
	if(pstmt != null) try{pstmt.close()}catch(exception e){}
	if(cn != null) try{ cn.close() }catch(exception e){}
}

1. Oracle跟SQL Server 2005的區別?
宏觀上:
1. 最大的區別在於平台,oracle可以運行在不同的平台上,sql server只能運行在windows平台上,由於windows平台的穩定性和安全性影響了sql server的穩定性和安全性
2. oracle使用的腳本語言為PL-SQL,而sql server使用的腳本為T-SQL
微觀上: 從數據類型,數據庫的結構等等回答 

2. 如何使用Oracle的游標?
1.  oracle中的游標分為顯示游標和隱式游標
2.  顯示游標是用cursor...is命令定義的游標,它可以對查詢語句(select)返回的多條記錄進行處理;隱式游標是在執行插入 (insert)、刪除(delete)、修改(update)和返回單條記錄的查詢(select)語句時由PL/SQL自動定義的。
3. 顯式游標的操作:打開游標、操作游標、關閉游標;PL/SQL隱式地打開SQL游標,並在它內部處理SQL語句,然后關閉它 

3. Oracle中function和procedure的區別?
1. 可以理解函數是存儲過程的一種
2. 函數可以沒有參數,但是一定需要一個返回值,存儲過程可以沒有參數,不需要返回值
3. 函數return返回值沒有返回參數模式,存儲過程通過out參數返回值, 如果需要返回多個參數則建議使用存儲過程
4. 在sql數據操縱語句中只能調用函數而不能調用存儲過程 

4. Oracle的導入導出有幾種方式,有何區別?
1. 使用oracle工具 exp/imp
2. 使用plsql相關工具
方法1. 導入/導出的是二進制的數據, 2.plsql導入/導出的是sql語句的文本文件 

5. Oracle中有哪幾種文件?
數據文件(一般后綴為.dbf或者.ora),日志文件(后綴名.log),控制文件(后綴名為.ctl) 

6. 怎樣優化Oracle數據庫,有幾種方式?
個人理解,數據庫性能最關鍵的因素在於IO,因為操作內存是快速的,但是讀寫磁盤是速度很慢的,優化數據庫最關鍵的問題在於減少磁盤的IO,就個人理解應該分為物理的和邏輯的優化, 物理的是指oracle產品本身的一些優化,邏輯優化是指應用程序級別的優化
物理優化的一些原則:
1. Oracle的運行環境(網絡,硬件等)
2. 使用合適的優化器
3. 合理配置oracle實例參數
4. 建立合適的索引(減少IO)
5. 將索引數據和表數據分開在不同的表空間上(降低IO沖突)
6. 建立表分區,將數據分別存儲在不同的分區上(以空間換取時間,減少IO)
   邏輯上優化:
1. 可以對表進行邏輯分割,如中國移動用戶表,可以根據手機尾數分成10個表,這樣對性能會有一定的作用
2. Sql語句使用占位符語句,並且開發時候必須按照規定編寫sql語句(如全部大寫,全部小寫等)oracle解析語句后會放置到共享池中
如: select * from Emp where name=?  這個語句只會在共享池中有一條,而如果是字符串的話,那就根據不同名字存在不同的語句,所以占位符效率較好
3. 數據庫不僅僅是一個存儲數據的地方,同樣是一個編程的地方,一些耗時的操作,可以通過存儲過程等在用戶較少的情況下執行,從而錯開系統使用的高峰時間,提高數據庫性能
4. 盡量不使用*號,如select * from Emp,因為要轉化為具體的列名是要查數據字典,比較耗時
5. 選擇有效的表名
對於多表連接查詢,可能oracle的優化器並不會優化到這個程度, oracle 中多表查詢是根據FROM字句從右到左的數據進行的,那么最好右邊的表(也就是基礎表)選擇數據較少的表,這樣排序更快速,如果有link表(多對多中間表),那么將link表放最右邊作為基礎表,在默認情況下oracle會自動優化,但是如果配置了優化器的情況下,可能不會自動優化,所以平時最好能按照這個方式編寫sql
6. Where字句 規則
Oracle 中Where字句時從右往左處理的,表之間的連接寫在其他條件之前,能過濾掉非常多的數據的條件,放在where的末尾, 另外!=符號比較的列將不使用索引,列經過了計算(如變大寫等)不會使用索引(需要建立起函數), is null、is not null等優化器不會使用索引 

7. 使用Exits Not Exits 替代 In  Not in
8. 合理使用事務,合理設置事務隔離性
數據庫的數據操作比較消耗數據庫資源的,盡量使用批量處理,以降低事務操作次數
7. Oracle中字符串用什么符號鏈接?
Oracle中使用 || 這個符號連接字符串 如 ‘abc’ || ‘d’
8. Oracle分區是怎樣優化數據庫的?
Oracle的分區可以分為:列表分區、范圍分區、散列分區、復合分區。
1.  增強可用性:如果表的一個分區由於系統故障而不能使用,表的其余好的分區仍可以使用;
2.  減少關閉時間:如果系統故障只影響表的一部份分區,那么只有這部份分區需要修復,可能比整個大表修復花的時間更少;
3.  維護輕松:如果需要得建表,獨產管理每個公區比管理單個大表要輕松得多;
4.  均衡I/O:可以把表的不同分區分配到不同的磁盤來平衡I/O改善性能;
5.  改善性能:對大表的查詢、增加、修改等操作可以分解到表的不同分區來並行執行,可使運行速度更快
6.  分區對用戶透明,最終用戶感覺不到分區的存在。
9. Oracle是怎樣分頁的?
Oracle中使用rownum來進行分頁, 這個是效率最好的分頁方法,hibernate也是使用rownum來進行oralce分頁的
select * from
  ( select rownum r,a from tabName where rownum <= 20 )
where r > 10
10. Oralce怎樣存儲文件,能夠存儲哪些文件?
Oracle 能存儲 clob、nclob、 blob、 bfile
Clob  可變長度的字符型數據,也就是其他數據庫中提到的文本型數據類型
Nclob 可變字符類型的數據,不過其存儲的是Unicode字符集的字符數據
Blob  可變長度的二進制數據
Bfile  數據庫外面存儲的可變二進制數據
11. Oracle中使用了索引的列,對該列進行where條件查詢、分組、排序、使用聚集函數,哪些用到了索引?
均會使用索引, 值得注意的是復合索引(如在列A和列B上建立的索引)可能會有不同情況
12. 數據庫怎樣實現每隔30分鍾備份一次?
通過操作系統的定時任務調用腳本導出數據庫
13. Oracle中where條件查詢和排序的性能比較?
Order by使用索引的條件極為嚴格,只有滿足如下情況才可以使用索引,
1.order by中的列必須包含相同的索引並且索引順序和排序順序一致
2. 不能有null值的列
所以排序的性能往往並不高,所以建議盡量避免order by
14. 解釋冷備份和熱備份的不同點以及各自的優點?
冷備份發生在數據庫已經正常關閉的情況下,將關鍵性文件拷貝到另外位置的一種說法
熱備份是在數據庫運行的情況下,采用歸檔方式備份數據的方法
冷備的優缺點:
1.是非常快速的備份方法(只需拷貝文件)
2.容易歸檔(簡單拷貝即可)
3.容易恢復到某個時間點上(只需將文件再拷貝回去)
4.能與歸檔方法相結合,作數據庫“最新狀態”的恢復。
5.低度維護,高度安全。
冷備份不足:
1.單獨使用時,只能提供到“某一時間點上”的恢復。
2.在實施備份的全過程中,數據庫必須要作備份而不能作其它工作。也就是說,在冷備份過程中,數據庫必須是關閉狀態。
3.若磁盤空間有限,只能拷貝到磁帶等其它外部存儲設備上,速度會很慢。
4.不能按表或按用戶恢復。  

熱備的優缺點 

1.可在表空間或數據文件級備份,備份時間短。
2.備份時數據庫仍可使用。
3.可達到秒級恢復(恢復到某一時間點上)。
4.可對幾乎所有數據庫實體作恢復。
5.恢復是快速的,在大多數情況下在數據庫仍工作時恢復。
  熱備份的不足是:
  1.不能出錯,否則后果嚴重。
  2.若熱備份不成功,所得結果不可用於時間點的恢復。
      3.因難於維護,所以要特別仔細小心,不允許“以失敗而告終”。
15. 解釋data block , extent 和 segment的區別?
data block 數據塊,是oracle最小的邏輯單位,通常oracle從磁盤讀寫的就是塊
extent 區,是由若干個相鄰的block組成
segment段,是有一組區組成
tablespace表空間,數據庫中數據邏輯存儲的地方,一個tablespace可以包含多個數據文件
16. 比較truncate和delete命令 ?
1. Truncate 和delete都可以將數據實體刪掉,truncate 的操作並不記錄到 rollback日志,所以操作速度較快,但同時這個數據部能恢復
2. Delete操作不騰出表空間的空間
3. Truncate 不能對視圖等進行刪除
4. Truncate是數據定義語言(DDL),而delete是數據操縱語言(DML)
17. 解釋什么是死鎖,如何解決Oracle中的死鎖?
簡言之就是存在加了鎖而沒有解鎖,可能是使用鎖沒有提交或者回滾事務,如果是表級鎖則不能操作表,客戶端處於等在狀態,如果是行級鎖則不能操作鎖定行
解決辦法:
1. 查找出被鎖的表
select b.owner,b.object_name,a.session_id,a.locked_mode
from v$locked_object a,dba_objects b
where b.object_id = a.object_id; 

select b.username,b.sid,b.serial#,logon_time
from v$locked_object a,v$session b
where a.session_id = b.sid order by b.logon_time;
2. 殺進程中的會話
alter system kill session "sid,serial#";
18. 簡述oracle中 dml、ddl、dcl的使用
Dml 數據操縱語言,如select、update、delete,insert
Ddl 數據定義語言,如create table 、drop table 等等
Dcl 數據控制語言, 如 commit、 rollback、grant、 invoke等
19. 說說oracle中的經常使用到得函數
Length 長度、 lower 小寫、upper 大寫, to_date 轉化日期, to_char轉化字符
Ltrim 去左邊空格、 rtrim去右邊空格,substr取字串,add_month增加或者減掉月份、to_number轉變為數字
20. 怎樣創建一個存儲過程, 游標在存儲過程怎么使用, 有什么好處?
附:存儲過程的一般格式,游標使用參考問題
1 .使用游標可以執行多個不相關的操作.如果希望當產生了結果集后,對結果集中的數據進行多種不相關的數據操作
2. 使用游標可以提供腳本的可讀性
3. 使用游標可以建立命令字符串,使用游標可以傳送表名,或者把變量傳送到參數中,以便建立可以執行的命令字符串.
但是個人認為游標操作效率不太高,並且使用時要特別小心,使用完后要及時關閉
存儲過程優缺點:
優點:
1. 存儲過程增強了SQL語言的功能和靈活性。存儲過程可以用流控制語句編寫,有很強的靈活性,可以完成復雜的判斷和較復雜的運算。
2. 可保證數據的安全性和完整性。
  3. 通過存儲過程可以使沒有權限的用戶在控制之下間接地存取數據庫,從而保證數據的安全。
      通過存儲過程可以使相關的動作在一起發生,從而可以維護數據庫的完整性。
3. 再運行存儲過程前,數據庫已對其進行了語法和句法分析,並給出了優化執行方案。這種已經編譯好的過程可極大地改善SQL語句的性能。 由於執行SQL語句的大部分工作已經完成,所以存儲過程能以極快的速度執行。
4. 可以降低網絡的通信量, 不需要通過網絡來傳送很多sql語句到數據庫服務器了
5. 使體現企業規則的運算程序放入數據庫服務器中,以便集中控制
       當企業規則發生變化時在服務器中改變存儲過程即可,無須修改任何應用程序。企業規則的特點是要經常變化,如果把體現企業規則的運算程序放入應用程序中,則當企業規則發生變化時,就需要修改應用程序工作量非常之大(修改、發行和安裝應用程序)。如果把體現企業規則的 運算放入存儲過程中,則當企業規則發生變化時,只要修改存儲過程就可以了,應用程序無須任何變化。
缺點:
1. 可移植性差
2. 占用服務器端多的資源,對服務器造成很大的壓力
3. 可讀性和可維護性不好 

Create  [or replace]  procedure 過程名字(參數 …)as
vs_ym_sn_end CHAR(6);     --同期終止月份
CURSOR cur_1 IS   --定義游標(簡單的說就是一個可以遍歷的結果集)
SELECT area_code,CMCODE,SUM(rmb_amt)/10000 rmb_amt_sn,SUM(usd_amt)/10000 usd_amt_sn
FROM BGD_AREA_CM_M_BASE_T
  WHERE ym >= vs_ym_sn_beg
  AND ym <= vs_ym_sn_end
GROUP BY area_code,CMCODE;
BEGIN
--用輸入參數給變量賦初值,用到了Oralce的SUBSTR TO_CHAR ADD_MONTHS TO_DATE 等很常用的函數。
vs_ym_beg := SUBSTR(is_ym,1,6);
vs_ym_end := SUBSTR(is_ym,7,6);
vs_ym_sn_beg := TO_CHAR(ADD_MONTHS(TO_DATE(vs_ym_beg,"yyyymm"), -12),"yyyymm");
vs_ym_sn_end := TO_CHAR(ADD_MONTHS(TO_DATE(vs_ym_end,"yyyymm"), -12),"yyyymm");
--先刪除表中特定條件的數據。
DELETE FROM xxxxxxxxxxx_T WHERE ym = is_ym;
  --然后用內置的DBMS_OUTPUT對象的put_line方法打印出影響的記錄行數,其中用到一個系統變量SQL%rowcount
DBMS_OUTPUT.put_line("del上月記錄="||SQL%rowcount||"條"); 

INSERT INTO xxxxxxxxxxx_T(area_code,ym,CMCODE,rmb_amt,usd_amt)
SELECT area_code,is_ym,CMCODE,SUM(rmb_amt)/10000,SUM(usd_amt)/10000
FROM BGD_AREA_CM_M_BASE_T
  WHERE ym >= vs_ym_beg
  AND ym <= vs_ym_end
GROUP BY area_code,CMCODE; 

DBMS_OUTPUT.put_line("ins當月記錄="||SQL%rowcount||"條");
--遍歷游標處理后更新到表。遍歷游標有幾種方法,用for語句是其中比較直觀的一種。
FOR rec IN cur_1 LOOP
  UPDATE xxxxxxxxxxx_T
  SET rmb_amt_sn = rec.rmb_amt_sn,usd_amt_sn = rec.usd_amt_sn
   WHERE area_code = rec.area_code
   AND CMCODE = rec.CMCODE
   AND ym = is_ym;
END LOOP;
COMMIT;
--錯誤處理部分。OTHERS表示除了聲明外的任意錯誤。SQLERRM是系統內置變量保存了當前錯誤的詳細信息。
EXCEPTION
   WHEN OTHERS THEN
      vs_msg := "ERROR IN xxxxxxxxxxx_p("||is_ym||"):"||SUBSTR(SQLERRM,1,500);
   ROLLBACK;
   --把當前錯誤記錄進日志表。
   INSERT INTO LOG_INFO(proc_name,error_info,op_date)
   VALUES("xxxxxxxxxxx_p",vs_msg,SYSDATE);
   COMMIT;
   RETURN;
END;
21. 怎樣創建一個一個索引,索引使用的原則,有什么優點和缺點
創建標准索引:
CREATE  INDEX 索引名 ON 表名 (列名)  TABLESPACE 表空間名;
創建唯一索引:
CREATE unique INDEX 索引名 ON 表名 (列名)  TABLESPACE 表空間名;
創建組合索引:
CREATE INDEX 索引名 ON 表名 (列名1,列名2)  TABLESPACE 表空間名;
創建反向鍵索引:
CREATE INDEX 索引名 ON 表名 (列名) reverse TABLESPACE 表空間名;
索引使用原則:
索引字段建議建立NOT NULL約束
經常與其他表進行連接的表,在連接字段上應該建立索引;
經常出現在Where子句中的字段且過濾性很強的,特別是大表的字段,應該建立索引;
可選擇性高的關鍵字 ,應該建立索引;
可選擇性低的關鍵字,但數據的值分布差異很大時,選擇性數據比較少時仍然可以利用索引提高效率
復合索引的建立需要進行仔細分析;盡量考慮用單字段索引代替:
A、正確選擇復合索引中的第一個字段,一般是選擇性較好的且在where子句中常用的字段上;
B、復合索引的幾個字段經常同時以AND方式出現在Where子句中可以建立復合索引;否則單字段索引;
C、如果復合索引中包含的字段經常單獨出現在Where子句中,則分解為多個單字段索引;
D、如果復合索引所包含的字段超過3個,那么仔細考慮其必要性,考慮減少復合的字段;
E、如果既有單字段索引,又有這幾個字段上的復合索引,一般可以刪除復合索引;
頻繁DML的表,不要建立太多的索引;
不要將那些頻繁修改的列作為索引列;
索引的優缺點:
有點:
1. 創建唯一性索引,保證數據庫表中每一行數據的唯一性
2. 大大加快數據的檢索速度,這也是創建索引的最主要的原因
3. 加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。
4. 在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。
缺點:
1. 索引創建在表上,不能創建在視圖上
2. 創建索引和維護索引要耗費時間,這種時間隨着數據量的增加而增加
3. 索引需要占物理空間,除了數據表占數據空間之外,每一個索引還要占一定的物理空間,如果要建立聚簇索引,那么需要的空間就會更大
4. 當對表中的數據進行增加、刪除和修改的時候,索引也要動態的維護,降低了數據的維護速度 

22. 怎樣創建一個視圖,視圖的好處, 視圖可以控制權限嗎?
create view 視圖名 as select 列名 [別名]  …  from 表 [unio [all] select … ] ]
好處:
1. 可以簡單的將視圖理解為sql查詢語句,視圖最大的好處是不占系統空間
2. 一些安全性很高的系統,不會公布系統的表結構,可能會使用視圖將一些敏感信息過慮或者重命名后公布結構
3. 簡化查詢
可以控制權限的,在使用的時候需要將視圖的使用權限grant給用戶
23. 怎樣創建一個觸發器, 觸發器的定義, 觸發器的游標怎樣定義
CREATE [OR REPLACE] TIGGER觸發器名 觸發時間 觸發事件
 ON表名
 [FOR EACH ROW]
 BEGIN
  pl/sql語句
    CURSOR  游標名 is  SELECT * FROM 表名 (定義游標)
  END
 其中:
 觸發器名:觸發器對象的名稱。
 由於觸發器是數據庫自動執行的,因此該名稱只是一個名稱,沒有實質的用途。
觸發時間:指明觸發器何時執行,該值可取:
before---表示在數據庫動作之前觸發器執行;
after---表示在數據庫動作之后出發器執行。
觸發事件:指明哪些數據庫動作會觸發此觸發器:
   insert:數據庫插入會觸發此觸發器;  

24. oracle創建表的幾種方式;應該注意些什么
不知道這個題目是不是記錯了,感覺很怪
1. 使用圖形工具創建表
2. 使用數據ddl語句創建表
3. 可以在plsql代碼中動態創建表
應該注意: 是否有創建表的權限, 使用什么表空間等
25. 怎樣將一個舊數據庫數據移到一個新的數據庫
1. Imp/exp將數據庫中的數據導入到新的庫中
2. 如果是存儲遷移直接將存儲設備掛到新機器上
26. 主鍵有幾種;
字符型,整數型、復合型
27. oracle的鎖又幾種,定義分別是什么;
1.  行共享鎖 (ROW SHARE)
2.  行排他鎖(ROW EXCLUSIVE)
3 . 共享鎖(SHARE)
4.  共享行排他鎖(SHARE ROW EXCLUSIVE)
5.  排他鎖(EXCLUSIVE)
使用方法:
SELECT * FROM order_master WHERE vencode="V002"
FOR UPDATE WAIT 5;
LOCK TABLE order_master IN SHARE MODE;
LOCK TABLE itemfile IN EXCLUSIVE MODE NOWAIT;
ORACLE鎖具體分為以下幾類:
1.按用戶與系統划分,可以分為自動鎖與顯示鎖
自動鎖:當進行一項數據庫操作時,缺省情況下,系統自動為此數據庫操作獲得所有有必要的鎖。
顯示鎖:某些情況下,需要用戶顯示的鎖定數據庫操作要用到的數據,才能使數據庫操作執行得更好,顯示鎖是用戶為數據庫對象設定的。
2 . 按鎖級別划分,可分為共享鎖與排它鎖
共享鎖:共享鎖使一個事務對特定數據庫資源進行共享訪問——另一事務也可對此資源進行訪問或獲得相同共享鎖。共享鎖為事務提供高並發性,但如拙劣的事務設計+共享鎖容易造成死鎖或數據更新丟失。
排它鎖:事務設置排它鎖后,該事務單獨獲得此資源,另一事務不能在此事務提交之前獲得相同對象的共享鎖或排它鎖。
3.按操作划分,可分為DML鎖、DDL鎖
DML鎖又可以分為,行鎖、表鎖、死鎖
行鎖:當事務執行數據庫插入、更新、刪除操作時,該事務自動獲得操作表中操作行的排它鎖。
表級鎖:當事務獲得行鎖后,此事務也將自動獲得該行的表鎖(共享鎖),以防止其它事務進行DDL語句影響記錄行的更新。事務也可以在進行過程中獲得共享鎖或排它鎖,只有當事務顯示使用LOCK TABLE語句顯示的定義一個排它鎖時,事務才會獲得表上的排它鎖,也可使用LOCK TABLE顯示的定義一個表級的共享鎖(LOCK TABLE具體用法請參考相關文檔)。
死鎖:當兩個事務需要一組有沖突的鎖,而不能將事務繼續下去的話,就出現死鎖。
如事務1在表A行記錄#3中有一排它鎖,並等待事務2在表A中記錄#4中排它鎖的釋放,而事務2在表A記錄行#4中有一排它鎖,並等待事務; 1在表A中記錄#3中排它鎖的釋放,事務1與事務2彼此等待,因此就造成了死鎖。死鎖一般是因拙劣的事務設計而產生。死鎖只能使用SQL下:alter system kill session "sid,serial#";或者使用相關操作系統kill進程的命令,如UNIX下kill -9 sid,或者使用其它工具殺掉死鎖進程。
DDL鎖又可以分為:排它DDL鎖、共享DDL鎖、分析鎖
排它DDL鎖:創建、修改、刪除一個數據庫對象的DDL語句獲得操作對象的 排它鎖。如使用alter table語句時,為了維護數據的完成性、一致性、合法性,該事務獲得一排它DDL鎖。
共享DDL鎖:需在數據庫對象之間建立相互依賴關系的DDL語句通常需共享獲得DDL鎖。
如創建一個包,該包中的過程與函數引用了不同的數據庫表,當編譯此包時,該事務就獲得了引用表的共享DDL鎖。
分析鎖:ORACLE使用共享池存儲分析與優化過的SQL語句及PL/SQL程序,使運行相同語句的應用速度更快。一個在共享池中緩存的對象獲得它所引用數據庫對象的分析鎖。分析鎖是一種獨特的DDL鎖類型,ORACLE使用它追蹤共享池對象及它所引用數據庫對象之間的依賴關系。當一個事務修改或刪除了共享池持有分析鎖的數據庫對象時,ORACLE使共享池中的對象作廢,下次在引用這條SQL/PLSQL語句時,ORACLE重新分析編譯此語句。
4.內部閂鎖
內部閂鎖:這是ORACLE中的一種特殊鎖,用於順序訪問內部系統結構。當事務需向緩沖區寫入信息時,為了使用此塊內存區域,ORACLE首先必須取得這塊內存區域的閂鎖,才能向此塊內存寫入信息。 

29. rowid,rownum的定義
1. rowid和rownum都是虛列
2. rowid是物理地址,用於定位oracle中具體數據的物理存儲位置
3. rownum則是sql的輸出結果排序,從下面的例子可以看出其中的區別。
30. oracle中存儲過程,游標和函數的區別
游標類似指針,游標可以執行多個不相關的操作.如果希望當產生了結果集后,對結果集中的數據進行多 種不相關的數據操作
函數可以理解函數是存儲過程的一種; 函數可以沒有參數,但是一定需要一個返回值,存儲過程可以沒有參數,不需要返回值;兩者都可以通過out參數返回值, 如果需要返回多個參數則建議使用存儲過程;在sql數據操縱語句中只能調用函數而不能調用存儲過程
31. 使用oracle 偽列刪除表中重復記錄:
Delete  table t  where t.rowid!=(select  max(t1.rowid)  from  table1 t1 where  t1.name=t.name)



面試筆試中最愛考的oracle 查詢題,歷來被稱為經典,面對經典查詢你會幾個呢?

 

使用scott/tiger用戶下的emp表和dept表完成下列練習,表的結構說明如下
emp員工表(empno員工號/ename員工姓名/job工作/mgr上級編號/hiredate受雇日期/sal薪金/comm佣金/deptno部門編號)
dept部門表(deptno部門編號/dname部門名稱/loc地點)
工資 = 薪金 + 佣金
1.列出至少有一個員工的所有部門。
2.列出薪金比“SMITH”多的所有員工。
3.列出所有員工的姓名及其直接上級的姓名。
4.列出受雇日期早於其直接上級的所有員工。
5.列出部門名稱和這些部門的員工信息,同時列出那些沒有員工的部門。
6.列出所有“CLERK”(辦事員)的姓名及其部門名稱。
7.列出最低薪金大於1500的各種工作。
8.列出在部門“SALES”(銷售部)工作的員工的姓名,假定不知道銷售部的部門編號。
9.列出薪金高於公司平均薪金的所有員工。
10.列出與“SCOTT”從事相同工作的所有員工。
11.列出薪金等於部門30中員工的薪金的所有員工的姓名和薪金。
12.列出薪金高於在部門30工作的所有員工的薪金的員工姓名和薪金。
13.列出在每個部門工作的員工數量、平均工資和平均服務期限。
14.列出所有員工的姓名、部門名稱和工資。
15.列出所有部門的詳細信息和部門人數。
16.列出各種工作的最低工資。
17.列出各個部門的MANAGER(經理)的最低薪金。
18.列出所有員工的年工資,按年薪從低到高排序。解答:
1.列出至少有一個員工的所有部門。(兩個表聯合查詢,及group by…having的用法)
select dname from dept where deptno in(select deptno from emp group by deptno having count(*)>1);
2.列出薪金比“SMITH”多的所有員工。(經典的自連接查詢)
select ename from emp where sal>(select sal from emp where ename like’SMITH’);
3.列出所有員工的姓名及其直接上級的姓名。(多次對自己查詢,為表的取個別名,內部查詢可以像對象一樣引用外部的對象的字 段,這里引用與編程中的作用域相似,即與{}類比)
select ename,(select ename from emp where empno in(a.mgr)) from emp a ;
4.列出受雇日期早於其直接上級的所有員工。(同上,日期可直接拿來比較)
select ename from emp a where HIREDATE<(select HIREDATE from emp where empno in(a.mgr));
5.列出部門名稱和這些部門的員工信息,同時列出那些沒有員工的部門(以emp表為主,左連接查詢)
select dname,emp.* from dept left join emp on dept.deptno=emp.deptno;
6.列出所有“CLERK”(辦事員)的姓名及其部門名稱。(域,注意())
select ename,(select dname from dept where deptno in(a.deptno)) as dname from emp a where JOB like’CLERK’;
7.列出最低薪金大於1500的各種工作。
select job from emp where sal>1500;
8.列出在部門“SALES”(銷售部)工作的員工的姓名,假定不知道銷售部的部門編號。(經典的兩個表連接)
select ename from emp where deptno=(select deptno from dept where dname like’SALES’);
9.列出薪金高於公司平均薪金的所有員工。(反復查自己)
select ename from emp where sal>( select avg( sal) from emp);
10.列出與“SCOTT”從事相同工作的所有員工。(排除自己)
select ename from emp where job in(select job from emp where ename like’SCOTT’) and ename!=’SCOTT’ ;
11.列出薪金等於部門30中員工的薪金的所有員工的姓名和薪金。(any的用法,且排擠)
select ename,sal from emp where sal=any(select sal from emp wheredeptno=30) and deptno!=30;
12.列出薪金高於在部門30工作的所有員工的薪金的員工姓名和薪金。(max的用法)
select sal,ename from emp where sal>(select max(sal) from emp where deptno=30);

13.列出在每個(每個是關鍵字,對此group by)部門工作的員工數量、平均工資和平均服務期限。(經典的group by用法)select deptno,count(*),avg(a.sal),avg(sysdate-HIREDATE) from emp a group by deptno;
14.列出所有員工的姓名、部門名稱和工資.(經典的兩個表的連接查詢,用具體的名稱替換一個表中的主鍵的id (解決很多人在實際運用中會遇到的不能綁定多列的問題),也可用where來查詢 ,與題5比較)
select ename,sal,(select dname from dept a where a.deptno=b.deptno)as dname from emp b;
15.列出所有部門的詳細信息和部門人數。(因為是*,將顯示dept和后面臨時表b的全部字段(注意:不只是dept的字段,注意*號))
select * from dept a left join (select deptno,count(*) from emp group by deptno) b on a.deptno=b.deptno ;
16.列出各種(與每個同義(參看題13))工作的最低工資。
select job,min(sal) from emp group by job ;

17.列出各個部門的MANAGER(經理,經理唯一,不用group by)的最低薪金。select min(sal) from emp where job like’MANAGER’;(因為MANAGER是值不是字段,所以不能用小寫)
18.列出所有員工的年工資,按年薪從低到高排序。(nvl:空轉化函數)
select ename,(sal+nvl(comm,0))*12 as sal from emp order by sal ;

 

Oracle基本操作筆試面試題之用戶、角色、權限管理

 

用戶創建、修改、刪除

用戶創建

create user username profile default identified by “user_passwd” default tablespace

tablespace_name account unlock;

修改用戶密碼:

alter user username identified by char_name

修改用戶使用狀態

alter user username account unlock

用戶賦權限:

grant connect,resource,select any table,update any table,delete any table,insert any

table,select

any dictionary,create any procedure,execute any procedure,create any TRIGGER,create

any view, unlimited tablespace

drop any view,create any sequence,select any sequence,drop any sequence,CREATE

DATABASE LINK,

CREATE PUBLIC DATABASE LINK,DROP PUBLIC DATABASE LINK,CREATE

ANY synonym,DROP ANY synonym,

CREATE PUBLIC synonym,DROP PUBLIC SYNONYM,SELECT_CATALOG_ROLE

to &u;

 

給某一個用戶賦予某張表的某種權限:

grant privilege_nameselect insert update) table_name to username;

例如:

grant update ON TABLE_NAME TO username;

grant delete ON TABLE_NAME TO username;

grant insert ON TABLE_NAME TO username;

 

用戶權限回收:

revoke role_name from username;

alter user username default role all;

 

用戶刪除:

Drop user username cascade (如果有數據,帶 cascade 參數)

查看用戶屬性和狀態:

select * from dba_users;

select * from dba_sys_privs

select * from dba_tab_privs

 

 

權限名稱:

administer database trigger

administer resource manager

alter any cluster

alter any dimension

alter any evaluation context

alter any index

alter any indextype

alter any library

alter any outline

alter any procedure

alter any role

alter any rule

alter any rule set

alter any sequence

alter any snapshot

alter any table

alter any trigger

alter any type

alter database

alter profile

alter resource cost

alter rollback segment

alter session

alter system

alter tablespace

alter user

analyze any

audit any

audit system

backup any table

 

debug any procedure

debug connect session

delete any table

dequeue any queue

drop any cluster

drop any context

drop any dimension

drop any directory

drop any evaluation context

drop any index

drop any indextype

drop any library

drop any operator

drop any outline

drop any procedure

drop any role

drop any rule

drop any rule set

drop any sequence

drop any snapshot

drop any synonym

drop any table

drop any trigger

drop any type

drop any view

drop profile

drop public database link

drop public synonym

drop rollback segment

drop tablespace


 

 

 

 

 

 

 

become user

comment any table

create any cluster

create any context

create any dimension

create any directory

create any evaluation context

create any index

create any indextype

create any library

create any operator

create any outline

create any procedure

create any rule

create any rule set

create any sequence

create any snapshot

create any synonym

create any table

create any trigger

create any type

create any view

create cluster

create database link

create dimension

create evaluation context

create indextype

create library

create operator

create procedure

create profile

create public database link

create public synonym

create role

create rollback segment

create rule

create rule set

create sequence

create session

create user

create view


 

 

 

 

 

 

 

drop user

enqueue any queue

execute any evaluation context

execute any indextype

execute any library

execute any operator

execute any procedure

execute any rule

execute any rule set

execute any type

exempt access policy

flashback any table

force any transaction

force transaction

global query rewrite

grant any object privilege

grant any privilege

grant any role

insert any table

lock any table

manage any queue

manage tablespace

on commit refresh

query rewrite

restricted session

resumable

select any dictionary

select any sequence

select any table

under any table

under any type

under any view

unlimited tablespace

update any table

create snapshot

create synonym

create table

create tablespace

create trigger

create type


 

 

 

 

 

 

 

2、角色創建、修改、刪除

 

 

角色創建

create role role_name;

角色權限修改

grant privilege_name to role_name

revoke privilege_name from role_name

角色刪除

drop role role_name

 

系統角色:

AQ_ADMINISTRATOR_ROLE

AQ_USER_ROLE

AUTHENTICATEDUSER

CONNECT

CTXAPP

DBA

DELETE_CATALOG_ROLE

EJBCLIENT

EXECUTE_CATALOG_ROLE

EXP_FULL_DATABASE

GATHER_SYSTEM_STATISTICS

HS_ADMIN_ROLE

WKUSER

WM_ADMIN_ROLE

XDBADMIN

 

 

 

3、權限增加和收回

 

IMP_FULL_DATABASE

JAVADEBUGPRIV

JAVAIDPRIV

JAVASYSPRIV

JAVAUSERPRIV

JAVA_ADMIN

JAVA_DEPLOY

LOGSTDBY_ADMINISTRATOR

OEM_MONITOR

RECOVERY_CATALOG_OWNER

RESOURCE

SALES_HISTORY_ROLE

SELECT_CATALOG_ROLE

grant privilege_name to role_name

revoke privilege_name from role_name

 

Oracle基本操作筆試面試題之表操作

1、單表創建

直接創建

Create table table_name

(


 

 

(增加權限)

(收回權限)

 

 

 

 

 

 

 

 

字段 1類型 1

字段 2類型 2

、、、、、

字段 n類型 n

) tablespace_name;

 

創建類似表

Create table table_name as select * from table_name1;

創建表結構:

Create table table_name as select * from table_name字段 1=字段 2

 

表查詢:

Select * from table_name;

Select * from table_name where條件

 

Select字段 1別名 1,字段 2

 

別名 2,字段 n別名 n from table_name


字段中可以進行代數運算,包括:+-×÷,countsunavgetrunkround等函數

表插入:

Insert字段 1,字段 2、、字段 n into table_name value (字段值 1,字段值 2、、字段值 n )

 

循環插入:

begin

for i in 1..10 loop

insert into table_name values (…);

end loop;

end;

 

表更新:

Update table_name set字段 1 where條件

表刪除:

drop table table_name

表記錄刪除:

delete table_name where條件;

truncate table table_name清空表記錄,保留表結構

表名修改:

rename table_name1 to table_name2

注意:表名修改后,索引還在

 

 

表遷移,(從一個表空間遷移到另外一個表空間)

alter table table_name move tablespace tablespace_name nologging parallele 4 ;

注意:將表從一個表空間遷移到另外一個表空間,必須進行索引重建,存儲過程、觸發器、其

他程序包都需要編譯,以免執行報錯。例如:

表壓縮:

不同表空間: alter table table_name move tablespace tablespace_name compress;

相同表空間:alter table table_name move compress;


 

 

 

 

 

 

 

 

 

表統計信息收集

exec dbms_stats.gather_table_stats(ownname => ‘username’,tabname

=>’table_name’,degree =>10,cascade =>true,estimate_percent =>25);

 

例如:

exec dbms_stats.gather_table_stats(ownname => ‘test’,tabname

=>’data_table1_name1′,degree =>4,cascade =>true,estimate_percent =>30);

 

 

select a.row2_id, sum(nvl(b.item_value, 0))

from zk.name _201001 a, zk.table_name _201001 b

where a.so_row1 = b.so_row1 and a.row_a in (1, 4, 5) and a.row2_id = XXXXXXX and

book_row3_id in (NNNNNXXX1, NNNNNXXX2, NNNNNXXX3, NNNNNXXX4,

NNNNNXXX5, NNNNNXXX6) group by a.row _id;

表語句執行很慢,檢查執行計划,zk.table_name_201001 b不引用索引,做表分析、重建索引都無

效,執行計划中均沒有引用索引,最后強制使用索引效果明顯,執行計划改變,索引引用。效果明

select /*+ index(b pk_table_name_201001)*/

a.serv_id, sum(nvl(b.item_value, 0))

from zk.name_201001 a, zk. table_name _201001 b

where a. so_row1 = b.so_row1 and a.busi_code in (1, 4, 5) and a.row2_id = XXXXXXX and

book_row3_id in (NNNNNXXX1, NNNNNXXX2, NNNNNXXX3, NNNNNXXX4,

NNNNNXXX5, NNNNNXXX6)

group by a.row2_id;

 

 

 

2、分區表創建

 

 

為了使大量的數據在讀寫操作和查詢中速度更快,Oracle提供了對表和索引進行分區的技術,

 

以改善大型應用系統的性能。使用分區的優點:

 

A、增強可用性:如果表的某個分區出現故障,表在其他分區的數據仍然可用;

 

B、維護方便:如果表的某個分區出現故障,需要修復數據,只修復該分區即可;

 

C、均衡I/O:可以把不同的分區映射到磁盤以平衡I/O,改善整個系統性能;

D、改善查詢性能:對分區對象的查詢可以僅搜索自己關心的分區,提高檢索速度

 

 

Oracle數據庫提供對表或索引的分區方法有三種:

 

1、范圍分區

 

2、Hash分區(散列分區)

 

3、列表分區

 

 

 

 

 

 

 

 

4、范圍—散列分區

 

5、范圍—列表分區

 

 

2.1、范圍分區表

分區表表創建:一般都是按照時間來創建

create table table_name

(

row1 char1 not null,

row2 char2 not null,

、、、、、、

rown  number not null

)

partition by range (paration_row)

(

partition partition_name1 values less than (to_date(‘value_name’, ‘yyyy-mm-dd’,

‘nls_calendar=gregorian’)) tablespace tablespace_name1,

partition partition_name2 values less than (to_date(‘value_name’, ‘yyyy-mm-dd’,

‘nls_calendar=gregorian’)) tablespace tablespace_name2,

、、、、、、、、、、

partition partition_namen values less than (to_date(‘value_name’, ‘yyyy-mm-dd’,

‘nls_calendar=gregorian’)) tablespace tablespace_namen,

partition partmax values less than (maxvalue)

tablespace ora_data

pctfree 10

initrans 16

maxtrans 255

storage

(

initial 64k

minextents 1

maxextents unlimited ))

表插入:

Insert into table_name1 as select * from table_name2

 

表分區刪除:

alter table表名 truncate partition分區名稱 drop storage;

注意:分區刪除以后,需要重新創建索引。

 

 

分區分割:

alter table table_name split partition partmax at(to_date(‘values_name’, ‘yyyy-mm-dd’)) into

(partition prtition_namexx tablespace tablespace_name , partition partmax);

 

分區查詢:

 

 

 

 

 

 

 

 

select * from table_name partition (partition_name);

 

2.2hash分區表(散列分區)

Hash分區表創建:hash分區表的分區數量一般是 2 n次冪,這樣記錄分布在各個分區上就

比較均勻,可以進行 I/O的均衡。

create table table_name

(

row1 char1 not null,

row2 char2 not null,

、、、、、、

rown  NUMBER not null

)

partition by hash (paration_row)

(

partition partition_name1 tablespace tablespace_name1,

partition partition_name2 tablespace tablespace_name2,

partition partition_name3 tablespace tablespace_name3

、、、、、、、、、、

partition partition_nameX tablespace tablespace_nameX

)

 

表插入:

insert into table_name1 as select * from table_name2

 

分區查詢:

Select * From table_name Partition (partition_name); hash分區表一般由於數據分布均衡性,查

詢不是

通過對分區的操作進行的。updateinsert操作同普通表。

 

2.3、列表分區表

散列分區表創建:

create table table_name

(

row1 char1 not null,

row2 char2 not null,

、、、、、、

rown  number not null

)

partition by list (paration_row)

(


partition   partition_name1

 

values

 

(row_value1,row_value3,row_value8)

 

tablespace


tablespace_name1,


partition   partition_name2

 

values

 

(row_value4,row_value6,row_value7)

 

tablespace


tablespace_name2,


 

 

 

 

 

 

 

partition


 

 

 

 

 

 

 

partition_name3


 

 

 

 

 

 

 

values


(row_value9,row_value10,row_value11,row_value12,row_value15)

tablespace tablespace_name3

、、、、、、、、、、

partition partition_nameX values (default) tablespace tablespace_nameX

)

 

表的插入、更新、刪除和普通表相同,在 hash分區和 list分區中,比較困難的操作是:從一張 5

千萬以上的表中,要刪除一千萬條記錄比較困,可以通過以下方法進行清理:

 

 

第一種方法:

a創建中間表和表備份,b進行數據插入,c進行鎖表,d進行表名修改,e進行索引創建

和存儲過程編譯,f進行表 truncate操作

第二種方法:直接創建 job進行 delete刪除:這樣長期做,會降低表的執行效果

a進行備份數據,b進行表記錄刪除,每次刪除 1000——2000條記錄,不然會發生鎖表,c

建索引,d進行表分析。

 

 

declare

v_lognum number; –數據庫中擁有的日志文件數

v_needarc number; –需要歸檔的日志文件數

begin

select count(1) into v_lognum from v$log;

loop

loop

select count(1) into v_needarc from v$archive;

if v_needarc < v_lognum – 1 then

exit;

end if;

end loop;


delete from

 

對象.table_name where條件 1 and條件 2 and rownum<1000;


if sql%rowcount = 0 then

exit;

end if;

commit;

end loop;

end;

––––––————— — – - – - – - – - – - – - – - – - – - – - – -

create or replace procedure procedure_name(exp_date1 varchar2 ,exp_date2 varchar2)

as

del_sql varchar2(1024);

v_c integer;

 

 

begin


 

 

 

 

 

 

 

del_sql:=’delete from對象.表名 a where exists (select 1 from對象.表名 b where

條件 1 and

條件 2 and、、、、

條件 nand rownum<1000′;

 

 

for i in 1..10000 loop

 

 

execute immediate del_sql using exp_date1,exp_date2;

if sql%rowcount = 0 then

exit;

end if;

commit;

 

 

end loop;

end procedure_name;

 

 

 

3、分區操作

 

 

添加分區

alter table table_partition_name add partition partition_name values less than

(to_date(‘row_values’,'yyyy-mm-dd’));

注意:以上添加的分區界限應該高於最后一個分區界限。

 

alter table table_partition_name

 

modify partition partition_name

 

add

 

subpartition


subpartition_name

values(‘row_values’);

 

刪除分區

以下代碼刪除表分區:

alter table table_partition_name drop partition partition_name storage;

注意:如果刪除的分區是表中唯一的分區,那么此分區將不能被刪除,要想刪除此分區,必須刪除

 

 

截斷分區

截斷某個分區是指刪除某個分區中的數據,並不會刪除分區,也不會刪除其它分區中的數據。當表

中即使只有一個分區時,也可以截斷該分區。通過以下代碼截斷分區:

alter table table_partition_name truncate partition partition_name;

 

合並分區

合並分區是將相鄰的分區合並成一個分區,結果分區將采用較高分區的界限,值得注意的是,不能

將分區合並到界限較低的分區。以下代碼實現了 partition_name1 partition_name分區的合並:

alter table table_partition_name merge partitions partition_name1,partition_name2 into partition

partition_name2;


 

 

 

 

 

 

 

拆分分區

拆分分區將一個分區拆分兩個新分區,拆分后原來分區不再存在。注意不能對 HASH類型的分

區進行拆分。

alter table table_partition_name sblit partition partition_name1

at(to_date(‘row_value’,'yyyy-mm-dd’))

into (partition partition_name1,partition partition_name2);

 

接合分區(coalesca)

結合分區是將散列分區中的數據接合到其它分區中,當散列分區中的數據比較大時,可以增加

散列分區,然后進行接合,值得注意的是,接合分區只能用於散列分區中。通過以下代碼進行接合

分區:

alter table table_hash_partition_name coalesca partition;

 

重命名表分區

以下代碼將 partition_name1更改為 partition_name2

alter table table_partition_name rename partition partition_name1 to partition_name2;

 

相關查詢

跨分區查詢

select sum( *) from

(select count(*) cn from table_partition_name partition (partition_name1)

union all

select count(*) cn from table_partition_name partition (partition_name2));

 

查詢表上有多少分區

select * from user_tab_partitions where table_name =’table_partition_name’

查詢索引信息

select object_name,object_type,tablespace_name,sum(value)

from v$segment_statistics

where statistic_name in (‘physical reads’,'physical write’,'logical reads’)and object_type=’index’

group by object_name,object_type,tablespace_name order by 4 desc

 

顯示數據庫所有分區表的信息:

select * from dba_part_tables

 

顯示當前用戶可訪問的所有分區表信息:

select * from all_part_tables

 

顯示當前用戶所有分區表的信息:

select * from USER_PART_TABLES

 

顯示表分區信息顯示數據庫所有分區表的詳細分區信息:

select * from dba_tab_partitions


 

 

 

 

 

 

 

顯示當前用戶可訪問的所有分區表的詳細分區信息:

select * from all_tab_partitions

 

顯示當前用戶所有分區表的詳細分區信息:

select * from user_tab_partitions

 

顯示子分區信息顯示數據庫所有組合分區表的子分區信息:

select * from dba_tab_subpartitions

 

顯示當前用戶可訪問的所有組合分區表的子分區信息:

select * from all_tab_subpartitions

 

顯示當前用戶所有組合分區表的子分區信息:

select * from user_tab_subpartitions

 

顯示分區列顯示數據庫所有分區表的分區列信息:

select * from dba_part_key_columns

 

顯示當前用戶可訪問的所有分區表的分區列信息:

select * from all_part_key_columns

 

顯示當前用戶所有分區表的分區列信息:

select * from user_part_key_columns

 

顯示子分區列顯示數據庫所有分區表的子分區列信息:

select * from dba_subpart_key_columns

 

顯示當前用戶可訪問的所有分區表的子分區列信息:

select * from all_subpart_key_columns

 

顯示當前用戶所有分區表的子分區列信息:

select * from user_subpart_key_columns

 

怎樣查詢出 oracle數據庫中所有的的分區表

select * from user_tables a where a.partitioned=’yes’

 

刪除一個表的數據是

truncate table table_name;

 

刪除分區表一個分區的數據是

alter table table_partition_name truncate partition partition_nameN drop storage;


 

 

 

 

 

 

 

4、表狀態查詢

 

 

Select * From Dba_Tab_Partitions Where Table_Name=’%表名%’;

Select owner,index_name,status,degree,table_name from dba_indexes where

table_name=’table_name ’;

select owner,bytes/1024/1024,segment_nam,segment_type,tablespace_name from dba_segments

where

segment_name=’table_name’ and segment_type=’TABLE’ ;

 

 

 

5DDL語句操作

 

 

創建表

基本語法:

create [global temporary] table table_name(

column_name type [constraint constraint_def default default_exp]

[,column_name type [constraint constraint_def default default_exp] …])

[on commit {delete | preserve} rows]

tablespace tab_space;

 

其中:

1)global temporary說明改表的行都是臨時的,這種表就稱為臨時表。

行的有效期由 on commit字句指定。臨時表對於所有的會話都是可見的,但是這些行則是特定於

某個會話的。

2)table_name指定了要分配給該表的名稱。

3)column_name指定了要分配給某個列的名稱。

4)type指定了對某個列的類型。

5)constraint_def指定了對某個列的約束的定義。

6)default_def指定了一個表達式,用來為某個列賦予默認值。

7)on commit控制臨時表中行的有效期。delete說明這些行在事務的末尾要被刪除。

preserve說明這些行在會話的末尾要被刪除。若對臨時表沒有指定 on commit選項,那末默認值是

delete

8)tab_space為該表指定表空間。若沒有指定表空間,該表就被存儲在該用戶的默認表空間中。

 

獲得有關表的信息可以通過如下操作獲取有關表的信息:

對表執行 describe命令。

desc order_status_temp

注意 desc SQL*PLUS命令,在 SQL中不能執行。

查詢 user_tables,它是數據字典的一部分。另:查詢用戶可訪問的表的相關信息,可以查詢

all_tables

select table_name, tablespace_name, temporary

from user_tables

where table_name in (‘table_name’, ‘ORDER_STATUS_TEMP’);


 

 

 

 

 

 

 

 

 

獲得表中列的信息

user_tab_columns中可以獲得有關表中各列的信息,另:通過訪問 all_tab_columns,可以獲得有關

可以訪問的表中所有列的信息。

select column_name, data_type, data_length, data_precision, data_scale

from user_tab_columns

where table_name = ‘table_name’;

 

修改表

alter table語句可以用於對表進行修改。

alter table語句可以執行以下任務:

1)添加、修改、刪除列;

2)添加或刪除約束;

3)啟用或禁用約束。

 

添加列

alter table table_name add modified_by integer;

alter table table_name add rowname類型 [date default sysdate not null];

 

修改列

1)修改列的長度,條件是該列的類型的長度可以修改,比如 char varchar2

2)修改數字列的精度;

3)修改列的數據類型;

4)修改列的默認值。

 

修改列的長度

alter table table_name modify rowname類型(長度);

只有在表中還沒有任何行或所有列都為空值的情況下才可以減小列的長度。

修改數字列的精度

alter table table_name modify column類型;

只有在表中還沒有任何行或列為空值時才可以減小數字列的精度。

 

 

修改列的數據類型

alter table table_name modify column類型;

 

若一個表中還沒有任何行或列為空值,就可以將列修改為任何一種數據類型。否則,就只能將列的

數據類型修改為一種兼容的數據類型。

例如,可以將 varchar2類型修改為 char,條件是沒有縮短列的長度;但是不能將 date修改為

number

 

修改列的默認值

alter table table_name modify column column_name;

默認值只適用於新插入表中的行。

 

 

 

 

 

 

 

 

刪除列

alter table table_name drop column column_name;

 

重命名表

rename語句可以用於對表進行重命名。

rename table_name1 table_name2;

刪除表數據,保留表結構

truncate table table_name

 
 

視圖是基於一張表或多張表或另外一個視圖的邏輯表。視圖不同於表,視圖本身不包含任何數

據。表是實際獨立存在的實體,是用於存儲數據的基本結構。而視圖只是一種定義,對應一個查詢

語句。視圖的數據都來自於某些表,這些表被稱為基表。通過視圖來查看表,就像是從不同的角度

來觀察一個(或多個)表。

 

 

視圖有如下一些優點:

a可以提高數據訪問的安全性,通過視圖往往只可以訪問數據庫中表的特定部分,限制了用戶訪

問表的全部行和列。

b簡化了對數據的查詢,隱藏了查詢的復雜性。視圖的數據來自一個復雜的查詢,用戶對視圖的

檢索卻很簡單。

c一個視圖可以檢索多張表的數據,因此用戶通過訪問一個視圖,可完成對多個表的訪問。

d視圖是相同數據的不同表示,通過為不同的用戶創建同一個表的不同視圖,使用戶可分別訪

問同一個表的不同部分。視圖可以在表能夠使用的任何地方使用,但在對視圖的操作上同表相

比有些限制,特別是插入和修改操作。對視圖的操作將傳遞到基表,所以在表上定義的約束條件和

觸發器在視圖上將同樣起作用。

 

 

 

1、視圖創建

 

 

create [or replace] [force|noforce] view view_name

[(alias[,alias]…)]

as subquery

[with check option [constraint constraint]]

[with read only]

例如:

創建視圖 empv,該屬兔僅包含 10部門雇員的細節信息。

create view empv

as select empno,ename,job

from  emp

where deptno=10;

 

別名的使用

 

 

 

 

 

 

 

 

1create or replace view salv

as select empno employee_id,ename name,sal salary

from emp where deptno=30;

 

2create or replace view salv

(employee_id,name,salary)

as select empno,ename,sal

from emp

where deptno=30;

 

創建復雜視圖

例:創建一個基於兩個表並且含有組函數的復雜視圖

create or replace view dept_sum_v(name,minsal,maxsal,avgsal)

as select d.dname,min(e.sal),max(e.sal),avg(e.sal)

from emp e,dept d where e.deptno=d.deptno group by d.dname;

 

 

 

2、視圖操作

 

 

查看視圖

數據字典 USER_VIEWS

select view_name,text from user_views;

 

從視圖檢索數據

select * from salv;

 

視圖上執行 DML操作

a)如果視圖包含以下內容,則不能實現對數據的修改:

-GROUP函數、GROUP BY子句、DISTINCT關鍵字

-使用表達式定義的列

-ROWNUM偽列

 

b)如果視圖中包含以下內容則不能刪除數據行

-GROUP函數

-GROUP BY子句

-DISTINCT關鍵字

-ROWNUM偽列

 

WITH CHECK OPTION子句

-如果要確保在視圖上執行的插入、更新操作僅限於一定的范圍,便可使用 WITH CHECK

OPTION子句

例:

create or replace view empv

as select * from emp where deptno=20


 

 

 

 

 

 

 

with check option constraint empv_ck;

 

測試一:update empv set deptno=10 where empno=7369

結果:

ERROR位於第 1:

ORA-01402:視圖 WITH CHECK OPTIDN違反 where子句

 

測試二:update empv set sal=2000 where empno=7369

結果:已更新 1行。

 

拒絕 DML操作

-在視圖定義時使用 WITH READ ONLY選項可以確保不能對視圖執行 DML操作

例:

create or replace view empv(employee_id,employ_name,job_title)

as select empno,ename,job from emp where deptno=10

with read only;

 

 

 

3、視圖刪除

 

 

刪除視圖並不會刪除數據,因為視圖是基於數據庫中的基表

DROP VIEW view_name;

例:DROP VIEW empv;

 

Oracle基本操作筆試面試題之索引、約束操作

Oracle的“索引”對象,與表關聯的可選對象,提高SQL查詢語句的速度;

索引直接指向包含所查詢值的行的位置,減少磁盤I/O;

與所索引的表是相互獨立的物理結構;

Oracle自動使用並維護索引,插入、刪除、更新表后,自動更新索引;

語法:CREATE INDEX index ON table (column[, column]…);

B-tree結構( bitmap)

 

 

1、單表索引

 

 

索引創建:

 

create [unique | bitmap] index index_name on table_name(col_name) pctfree 20


storage(initial 100k next 100k pctincrease

tablespace_name;

 

0 maxextents 100) tablespace


 

 

 

 

 

 

 

 

 

索引重建:

 

重建索引(可以同時使用存儲子句和參數,不重建時也可直接使用)

alter index index_name rebuild tablespace tablespace_name nologging parallel 4;

alter index index_name noparallel;

 

在線重建索引.可以減少加鎖時間,從而開放使用 DML類型操作

alter index index_name rebuild tablespace tablespace_name nologging online;

手動拓展索引的空間

alter index index_name allocate extent;

收回未用到的空間

alter index index_name deallocate unused;

索引碎片整理

alter index index_name coalesce;

標識索引是否使用過

alter index index_name monitoring usage;

查詢:

select * from v$object_usage;

取消監控

alter index index_name nomonitoring usage

索引壓縮:

alter index index_name rebuild nologging online tablespace tablespace_name compress;

 

 

索引刪除:

 

drop index index_name

 

 

索引查看:

 

索引相關信息

select owner,index_name,table_name,tablespace_name,index_type,degree,status

from dba_indexes;

 

索引列對照信息

select index_name,table_name,column_name,index_owner,table_owner

from dba_ind_columns;

 

索引存儲信息

select index_name,pct_free,pct_increase,initial_extent,next_extent,min_extents,

max_extents from dba_indexes;


 

 

 

 

 

 

 

2、分區表索引

 

 

索引創建:

局部索引

create index index_name on table_name (column)

local

(

partition partition_name1 tablespace index_tablespace_name1,

partition partition_name2 tablespace index_tablespace_name2,

partition partition_name3 tablespace index_tablespace_name3

)

全局索引

create [unique] index index_name on table_name(column)

global partition by range(column)

(

partition partition_name1 value less than(first range value) tablespace

index_tablespace_name1,

partition partition_name2 value less than(second range value) tablespace

index_tablespace_name 2,

、、、、、、、

partition partition_nameN value less than(maxvalue) tablespace index_tablespace_nameN

)

 

 

create [unique] index index_name on table_name(column,[column2])

global partition by hash(column,[column2])

(

partition partition_name1 tablespace index_tablespace_name1,

partition partition_name2 tablespace index_tablespace_name 2,

、、、、、、、、

partition partition_nameN tablespace index_tablespace_nameN

)

 

索引重建:

alter index index_name rebuild tablespace tablespace_name nologging online parallel 4;

alter index index_name noparallel;

 

索引刪除:

drop index index_name;

 

索引查看:

索引相關信息

select owner,index_name,table_name,tablespace_name,index_type,degree,status from

dba_indexes;


 

 

 

 

 

 

 

索引列對照信息

select index_name,table_name,column_name,index_owner,table_owner from

dba_ind_columns;

索引存儲信息

select index_name,pct_free,pct_increase,initial_extent,next_extent,min_extents,max_extents

from dba_indexes;

 

 

 

3、主鍵、約束和唯一索引

 

 

 

唯一索引

唯一索引不允許兩行具有相同的索引值。如果現有數據中存在重復的鍵值,則大多數數據庫都

不允許將新創建的唯一索引與表一起保存。當新數據將使表中的鍵值重復時,數據庫也拒絕接受此

數據。例如,如果在 books_table表中的書名 (book_name)列上,創建了唯一索引,則所有書不能

同名。

 

 

主鍵索引

主鍵索引是唯一索引的特殊類型,數據庫表通常有一列或列組合,其值用來唯一標識表中的每一

行。該列稱為表的主鍵。在數據庫關系圖中為表定義一個主鍵將自動創建主鍵索引,主鍵索引是唯

一索引的特殊類型。主鍵索引要求主鍵中的每個值是唯一的。當在查詢中使用主鍵索引時,它還允

許快速訪問數據。

 

 

主鍵和唯一索引的一些比較:

(1)對於主健 unique/constraint oracle自動建立唯一索引

(2)主鍵不一定只包含一個字段,所以如果你在主鍵的其中一個字段建唯一索引還是必要的

(3)主健可作外健,唯一索引不可,

(4)主健不可為空,唯一索引可,

(5)主健也可是多個字段的組合.

(6)主鍵不同的是

a. not null屬性 b.每個表只能有一個

 

約束和唯一索引比較:

主鍵索引和主鍵約束的創建與刪除順序

創建主鍵索引 –>創建主鍵約束刪除主鍵約束 –>刪除主鍵索引

 

A分區字段不是主鍵的情況下,只可以創建全局分區索引,不可以創建本地主鍵分區索引.只有分

區字段為主鍵時才可以創建本地主鍵分區索引.

B如果創建本地唯一分區索引,除指定索引字段外還要加上表分區字段.這種索引意義不大:因為

這樣

成復合索引,索引改變,約束也改變了.

C如果創建非唯一索引則不需要表分區字段.

D創建全局分區索引后可以創建約束.


 

 

 

 

 

 

 

 

 

唯一索引創建:

create unique index index_name on table_name (column)

local

(

partition partition_name1 tablespace index_tablespace1,

partition partition_name2 tablespace index_tablespace2,

、、、、、、

partition partition_nameN tablespace index_tablespaceN

)

單表創建唯一索引:create unique index index_name on table_name (column);

 

唯一索引重建:

alter index index_name rebuild tablespace tablespace_name nologging parallel 8 online

alter index index_name noparallel;

 

唯一索引刪除:

如果有約束:先關閉約束 alter table table_name1 disable constraint constraint_name cascade;

drop索引:drop index index_name

 

索引查看:

DBA查看索引分區

select * from dba_ind_partitions

USER查看索引分區

select * from user_ind_partitions

DBA查看索引分區類型

select * from dba_part_indexes

USER查看索引分區類型

select * from user_part_indexes

 

約束創建:

在數據庫中使用約束(constraints)是為了在該數據庫中實施所謂的業務規則其實就是防止非法

信息進入數據庫,滿足管理員和應用開發人員所定義的規則集.

ORACLE使用完整性約束(integrity constraints)防止不合法的數據寫入數據庫,管理員和開發人

員可以定義完整性規則,增強商業規則,限制數據表中的數據.如果一個 DML語句執行的任何結果破

壞了完整性約束,ORACLE就會回滾語句,返回錯誤信息.

約束是通過使用 create table alter table語句生成的.(建立表時或者表建立后修改都可)如果相關

的約束定義在單列上,可以在列這一級指定約束的定義;多列約束必須定義在數據表級,相關的列要

在括號中指定,用逗號分隔.如果沒有為約束提供一個名字,那么 ORACLE會分配一個系統生成的唯

一名字, SYS_開頭,你可以使用關鍵字 CONSTRAINTS后面跟隨相關的約束名字來為約束指定名

.

 

ORACLE支持五種類型的完整性約束

NOT NULL (非空)–防止 NULL值進入指定的列,在單列基礎上定義,默認情況下,ORACLE允許

 

 

 

 

 

 

 

 

在任何列中有 NULL.

CHECK (檢查)–檢查在約束中指定的條件是否得到了滿足.

UNIQUE (唯一)–保證在指定的列中沒有重復值.在該表中每一個值或者每一組值都將是唯一的.

PRIMARY KEY (主鍵)–用來唯一的標識出表的每一行,並且防止出現 NULL,一個表只能有一

個主鍵約束.

POREIGN KEY (外部鍵)–通過使用公共列在表之間建立一種父子(parent-child)關系,在表上定

義的外部鍵可以指向主鍵或者其他表的唯一鍵.

約束定義存儲在數據字典中,查詢 user_constraints可以獲得相關信息.

 

定義約束

create table [schema.]table

(column datatype [default expr]

[column_constraint],

[table_constraint][,...]);

 

創建約束:

create table employees

(employee_id number(6),

first_name varchar2(20),

job_id varchar2(10) not null,

constraints emp_emp_id_pk primary key (employee_id));

列級的約束定義

column [CONSTRAINT constraint_name] constraint_type,

表級約束的定義

column,..

[constraint constraint_name] constraint_type (column,…)

 

NOT NULL約束

只能定義在列級,不能定義在表級:

create table table_name1

(row_id number(6),

row_time varchar2(25) not null,

row_salary number(8,2),

row_pct number(2,2),

row_date date constraint constraint_name1 not null);

 

UNIQUE約束

用來保護一個表中的一個或者多個列沒有任何兩行在收到保護的列中具有重復的數據.ORACLE

唯一鍵列上自動生成一個唯一索引以實現唯一性:

create table table_name1

(row_id number(6),

row_time varchar2(25) not null,


 

 

 

 

 

 

 

row_salary number(8,2),

row_pct number(2,2),

row_date date constraint constraint_name1 UNIQUE(row_id));

 

PRIMARY KEY約束

唯一鍵的所有特征都適用於主鍵約束,只是在主鍵列中不允許有 NULL.一個表只能有一個主鍵:

create table table_name1

(row_id number(6),

row_time varchar2(25) not null,

row_salary number(8,2),

row_pct number(2,2),

row_date date constraint constraint_name1 PRIMARY KEY(row_id));

 

foreign key約束

用來保護一個表中的一個或者多個列,它會通過一個主鍵主鍵或者唯一鍵保證對於每個非 NULL

值在數據庫的其他地方都有一個數據可用.這個外部鍵就是在生成此約束的表(子表)中的一個或多

個列,在父級表和子表中,相關列的數據類型必須匹配.外部鍵列和引用鍵(reference key)列可以位於

相同的表中(自引用完整性約束).

create table table_name1

(row_id number(6),

row_time varchar2(25) not null,

row_salary number(8,2),

row_pct number(2,2),

row_date date not null,

dep_id number(6),

constraint constraint_name1 foreign key(row_id) references table_name2(dep_id),

constraint constraint_name2 unique(dep_id));

 

上例中是在表級定義外部鍵約束,如果在列級定義,不同的是:

create table table_name1

(…,

dep_id number(4) constraint constraint_name1 references table_name2(dep_id),

…);

//沒有關鍵字 FOREIGN KEY

FOREIGN KEY約束還有兩個關鍵字是

ON DELETE CASCADE –當刪除所引用的父表記錄時,刪除子表中相關的記錄

ON DELETE SET NULL–與上面不同的是刪除時,轉換子表中相關記錄為 NULL

默認情況下,如果沒有指定以上兩個中任一,則父表中被引用的記錄將不能被刪除.

 

CHECK約束

[CONSTRAINT <constraint name>] CHECK (<condition> )

這里 CHECK子句中的 CONDITION應該求值為一個布爾值結果,並且可以引用相同行中其他列的

;

能包含子查詢,序列,環境函數(SYSDATE,UID,USER,USERENV)和偽列

 

 

 

 

 

 

 

 

(ROWNUM,LEVEL,CURRVAL,NEXTVAL),一個列上可以定義多個 CHECK約束,如果所定義的條

件為

FALSE,則語句將回滾.

CREATE TABLE table_name1

(…,

row_sal NUMBER(8,2) CONSTRAINT constraint_name1 CHECK (row_sal>0),

…);

 

添加約束

alter table table_name1

ADD CONSTRAINT constraint_name FOREIGN KEY(rowmagr_id) REFERENCES

table_name2(name_id);

 

刪除約束

alter table table_name1

drop constraint constraint_name;

alter table table_name1

drop primary key cascade;

對於 NOT NULL約束, ALTER TABLE MODIFY子句來刪除

alter table table_name1 modify row_name null;

 

關閉約束

alter table table_name1

disable constraint constraint_name cascade; //如果沒有被引用則不需 CASCADE關鍵字

當你生成一個約束時,約束自動打開(除非你指定了 DISABLE子句,當用 DISABLE關閉 UNIQUE

PRIMARY KEY約束時,ORACLE會自動刪除相關的唯一索引,再次打開時,ORACLE又會自動

建立.

 

打開約束

alter table table_name enable constraint constraint_name;

//注意,打開一個先前關閉的被引用的主鍵約束,並不能自動打開相關的外部鍵約束

 

約束信息查看:

可以從 USER_CONSTRAINTS表和 USER_CONS_COLUMNS視圖中查詢約束的信息

select constraint_name,constraint_type,search_condition

from user_constraints

where table_name=’table_name1′;

 

約束類型

C–CHECK NOT NULL都算為 C TYPE

P–PRIMARY KEY

R–REFERENTIAL INTEGRITY就是外部鍵約束

U–UNIQUE


 

 

 

 

 

 

 

select constraint_name,column_name

from user_cons_columns

where table_name=’table_name1′;

 Oracle基本操作筆試面試題之存儲過程/job/函數/觸發器操作

1、存儲過程和函數

 

 

存儲過程和函數也是一種 pl/sql塊,是存入數據庫的 pl/sql塊。但存儲過程和函數不

同於已經介紹過的 pl/sql程序,我們通常把 pl/sql程序稱為無名塊,而存儲過程和函數

是以命名的方式存儲於數據庫中的。和 pl/sql程序相比,存儲過程有很多優點,具體歸

納如下:

a)存儲過程和函數以命名的數據庫對象形式存儲於數據庫當中。存儲在數據庫中的優

點是很明顯的,因為代碼不保存在本地,用戶可以在任何客戶機上登錄到數據庫,並調

用或修改代碼。

b)存儲過程和函數可由數據庫提供安全保證,要想使用存儲過程和函數,需要有存儲

過程和函數的所有者的授權,只有被授權的用戶或創建者本身才能執行存儲過程或調用

函數。

c)存儲過程和函數的信息是寫入數據字典的,所以存儲過程可以看作是一個公用模塊,

用戶編寫的 pl/sql程序或其他存儲過程都可以調用它(但存儲過程和函數不能調用 pl/sql

程序)。一個重復使用的功能,可以設計成為存儲過程,比如:顯示一張工資統計表,

可以設計成為存儲過程;一個經常調用的計算,可以設計成為存儲函數;根據雇員編號

返回雇員的姓名,可以設計成存儲函數。

d)像其他高級語言的過程和函數一樣,可以傳遞參數給存儲過程或函數,參數的傳遞

也有多種方式。存儲過程可以有返回值,也可以沒有返回值,存儲過程的返回值必須通

過參數帶回;函數有一定的數據類型,像其他的標准函數一樣,我們可以通過對函數名

的調用返回函數值。

存儲過程和函數需要進行編譯,以排除語法錯誤,只有編譯通過才能調用。

創建存儲過程,需要有 create procedure或 create any procedure的系統權限。該權限可由

系統管理員授予。創建一個存儲過程的基本語句如下:

 

create [or replace] procedure存儲過程名[(參數[in|out|in out]數據類型…)]

{as|is}

[說明部分]

begin

可執行部分

[exception

錯誤處理部分]

end [過程名];

 

其中:可選關鍵字 or replace表示如果存儲過程已經存在,則用新的存儲過程覆

蓋,通常用於存儲過程的重建。參數部分用於定義多個參數(如果沒有參數,就可以省

 

 

 

 

 

 

 

 

略)。參數有三種形式:in、out和 in out。如果沒有指明參數的形式,則默認為 in,關

鍵字 as也可以寫成 is,后跟過程的說明部分,可以在此定義過程的局部變量,編寫存

儲過程可以使用任何文本編輯器或直接在 sql*plus環境下進行,編寫好的存儲過程必須

要在 sql*plus環境下進行編譯,生成編譯代碼,原代碼和編譯代碼在編譯過程中都會被

存入數據庫。編譯成功的存儲過程就可以在 oracle環境下進行調用了。一個存儲過程

在不需要時可以刪除。刪除存儲過程的創建者或者擁有 drop any procedure系統權限的

人。刪除存儲過程的語法如下:

 

語法格式:drop procedure存儲過程名;

 

如果要重新編譯一個存儲過程,則只能是過程的創建者或者擁有 alter any procedure

系統權限的人。語法如下:

 

alter procedure存儲過程名 compile

 

執行(或調用)存儲過程的人是過程的創建者或是擁有 execute any procedure系統權

限的人或是被擁有者授予 execute權限的人。執行的方法如下:

方法 1:

execute模式名.存儲過程名[(參數...)];

方法 2:

begin

模式名.存儲過程名[(參數...)];

end;

 

【訓練 1】創建一個顯示雇員總人數的存儲過程。

步驟 1:登錄 scott賬戶(或學生個人賬戶)

步驟 2:在 sql*plus輸入區中,輸入以下存儲過程:

create or replace procedure dyk_count

as

v_total1 number(10);

v_total2 number(10);

v_total3 number(10);

begin

select count(*) into v_total1 from dyk_table1;

dbms_output.put_line(雇員總人數為:||v_total1);

delete dyk_table1 where owner In (‘XDB’,‘CTSSYS’,‘OUTLN’,‘WMSYS’);

select count(*) into v_total2 from dyk_table1;

dbms_output.put_line(剩余總人數為:||v_total2);


insert into dyk_table1 nologging

 

select * from dba_objects;


select count(*) into v_total3 from dyk_table1;

dbms_output.put_line(增加后的總人數為:||v_total3);

end;

 

步驟 3:按執行按鈕進行編譯。

 

 

 

 

 

 

 

 

如果存在錯誤,就會顯示:警告:創建的過程帶有編譯錯誤。

如果存在錯誤,對腳本進行修改,直到沒有錯誤產生。

如果編譯結果正確,將顯示:(sql代碼)

過程已創建。

步驟 4:調用存儲過程,在輸入區中輸入以下語句並執行:

sql代碼

set serverout on  / sql提示符下輸出存儲過程變量值

execute dyk_count;

顯示結果為:

雇員總人數為:337386

剩余總人數為:336456

增加后的總人數為:386254

 

說明:在該訓練中,v_total變量是存儲過程定義的局部變量,用於接收查詢到的雇員總人數。

注意:在 sql*plus中輸入存儲過程,按執行按鈕是進行編譯,不是執行存儲過程。如果在存儲

過程中引用了其他用戶的對象,比如表,則必須有其他用戶授予的對象訪問權限。一個存儲過程一

旦編譯成功,就可以由其他用戶或程序來引用。但存儲過程或函數的所有者必須授予其他用戶執行

該過程的權限。

存儲過程沒有參數,在調用時,直接寫過程名即可。

【訓練 2】在 pl/sql程序中調用存儲過程。

步驟 1:登錄 scott賬戶。

步驟 2:授權 student賬戶使用該存儲過程,即在 sql*plus輸入區中,輸入以下的命令:

sql代碼

grant execute on emp_count to student

sql代碼

授權成功。

步驟 3:登錄 student賬戶,在 sql*plus輸入區中輸入以下程序:

sql代碼

set serveroutput on

begin

scott.emp_count;

end;

 

步驟 4:執行以上程序,結果為:

sql代碼

雇員總人數為:14

pl/sql過程已成功完成。

 

說明:在本例中,存儲過程是由 scott賬戶創建的,studen賬戶獲得 scott賬戶的授權后,才能調

用該存儲過程。

注意:在程序中調用存儲過程,使用了第二種語法。

 

【訓練 3

 

編寫顯示雇員信息的存儲過程 emp_list,並引用 emp_count存儲過程。

 

步驟 1:在 sql*plus輸入區中輸入並編譯以下存儲過程:

sql代碼

 

 

 

 

 

 

 

 

create or replace procedure emp_list

as

cursor emp_cursor is

select empno,ename from emp;

begin

for emp_record in emp_cursor loop

dbms_output.put_line(emp_record.empno||emp_record.ename);

end loop;

emp_count;

end;

 

過程已創建。

步驟 2:調用存儲過程,在輸入區中輸入以下語句並執行:

sql代碼

execute emp_list

 

 

execute emp_list

顯示結果為:

sql代碼

7369smith

7499allen

7521ward

7566jones

執行結果:

雇員總人數為:14

pl/sql過程已成功完成。

說明:以上的 emp_list存儲過程中定義並使用了游標,用來循環顯示所有雇員的信息。然后調用已

經成功編譯的存儲過程 emp_count,用來附加顯示雇員總人數。通過 execute命令來執行 emp_list

存儲過程。

 

 

【練習 1】編寫顯示部門信息的存儲過程 dept_list,要求統計出部門個數。

參數傳遞:參數的作用是向存儲過程傳遞數據,或從存儲過程獲得返回結果。正確的使用參數可以

大大增加存儲過程的靈活性和通用性,參數的類型有三種,如下所示。

sql代碼

in定義一個輸入參數變量,用於傳遞參數給存儲過程

out定義一個輸出參數變量,用於從存儲過程獲取數據

in out定義一個輸入、輸出參數變量,兼有以上兩者的功能

 

in定義一個輸入參數變量,用於傳遞參數給存儲過程

out定義一個輸出參數變量,用於從存儲過程獲取數據

in out定義一個輸入、輸出參數變量,兼有以上兩者的功能

參數的定義形式和作用如下:

參數名 in數據類型 default值;

定義一個輸入參數變量,用於傳遞參數給存儲過程。在調用存儲過程時,主程序的實際參數可

 

 

 

 

 

 

 

 

以是常量、有值變量或表達式等。default關鍵字為可選項,用來設定參數的默認值。如果在調用

存儲過程時不指明參數,則參數變量取默認值。在存儲過程中,輸入變量接收主程序傳遞的值,但

不能對其進行賦值。

參數名 out數據類型;

定義一個輸出參數變量,用於從存儲過程獲取數據,即變量從存儲過程中返回值給主程序。

在調用存儲過程時,主程序的實際參數只能是一個變量,而不能是常量或表達式。在存儲過程中,

參數變量只能被賦值而不能將其用於賦值,在存儲過程中必須給輸出變量至少賦值一次。

參數名 in out數據類型 default值;

定義一個輸入、輸出參數變量,兼有以上兩者的功能。在調用存儲過程時,主程序的實際參數只能

是一個變量,而不能是常量或表達式。default關鍵字為可選項,用來設定參數的默認值。在存儲

過程中,變量接收主程序傳遞的值,同時可以參加賦值運算,也可以對其進行賦值。在存儲過程中

必須給變量至少賦值一次。

如果省略 inout in out,則默認模式是 in

【訓練 1】編寫給雇員增加工資的存儲過程 change_salary,通過 in類型的參數傳遞要增加工資的

雇員編號和增加的工資額。

步驟 1:登錄 scott賬戶。

步驟 2:在 sql*plus輸入區中輸入以下存儲過程並執行:

sql代碼

create or replace procedure change_salary(p_empno in number default 7788,p_raise number default

10)

as

v_ename varchar2(10);

v_sal number(5);

begin

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

update emp set sal=sal+p_raise where empno=p_empno;

dbms_output.put_line(‘雇員‘||v_ename||’的工資被改為‘||to_char(v_sal+p_raise));

commit;

exception

when others then

dbms_output.put_line(‘發生錯誤,修改失敗!‘);

rollback;

end;

 

過程已創建。

步驟 3:調用存儲過程,在輸入區中輸入以下語句並執行:

sql代碼

execute change_salary(7788,80)

顯示結果為:

sql代碼

雇員 scott的工資被改為 3080

說明:從執行結果可以看到,雇員 scott的工資已由原來的 3000改為 3080

參數的值由調用者傳遞,傳遞的參數的個數、類型和順序應該和定義的一致。如果順序不一致,可

以采用以下調用方法。如上例,執行語句可以改為:

 

 

 

 

 

 

 

 

execute change_salary(p_raise=>80,p_empno=>7788);

可以看出傳遞參數的順序發生了變化,並且明確指出了參數名和要傳遞的值,=>運算符左側是參

數名,右側是參數表達式,這種賦值方法的意義較清楚。

【練習 1】創建插入雇員的存儲過程 insert_emp,並將雇員編號等作為參數。

在設計存儲過程的時候,也可以為參數設定默認值,這樣調用者就可以不傳遞或少傳遞參數了。

 

【訓練 2

 

調用存儲過程 change_salary,不傳遞參數,使用默認參數值。

 

sql*plus輸入區中輸入以下命令並執行:

sql代碼

execute change_salary

顯示結果為:

sql代碼

雇員 scott的工資被改為 3090

說明:在存儲過程的調用中沒有傳遞參數,而是采用了默認值 7788 10,即默認雇員號為 7788

增加的工資為 10

 

【訓練 3

 

使用 out類型的參數返回存儲過程的結果。

 

步驟 1:登錄 scott賬戶。

步驟 2:在 sql*plus輸入區中輸入並編譯以下存儲過程:

sql代碼

create or replace procedure emp_count(p_total out number)

as

begin

select count(*) into p_total from emp;

end;

 

執行結果為:

sql代碼

過程已創建。

 

 

步驟 3:輸入以下程序並執行:

sql代碼

declare

v_empcount number;

begin

emp_count(v_empcount);

dbms_output.put_line(‘雇員總人數為:‘||v_empcount);

end;

 

顯示結果為:

sql代碼

雇員總人數為:14

pl/sql過程已成功完成。

 

說明:在存儲過程中定義了 out類型的參數 p_total,在主程序調用該存儲過程時,傳遞了參數

v_empcount。在存儲過程中的 select…into…語句中對 p_total進行賦值,賦值結果由 v_empcount


 

 

 

 

 

 

 

變量帶回給主程序並顯示。

以上程序要覆蓋同名的 emp_count存儲過程,如果不使用 or replace選項,就會出現以下錯誤:

sql代碼

error位於第 1:

ora-00955:名稱已由現有對象使用。

【練習 2】創建存儲過程,使用 out類型參數獲得雇員經理名。

 

【訓練 4

 

使用 in out類型的參數,給電話號碼增加區碼。

 

步驟 1:登錄 scott賬戶。

步驟 2:在 sql*plus輸入區中輸入並編譯以下存儲過程:

sql代碼

create or replace procedure add_region(p_hpone_num in out varchar2)

as

begin

p_hpone_num:=’0755-’||p_hpone_num;

end;

執行結果為:

過程已創建。

步驟 3:輸入以下程序並執行:

sql代碼

set serveroutput on

declare

v_phone_num varchar2(15);

begin

v_phone_num:=’26731092′;

add_region(v_phone_num);

dbms_output.put_line(‘新的電話號碼:‘||v_phone_num);

end;

 

顯示結果為:

sql代碼

新的電話號碼:0755-26731092

pl/sql過程已成功完成。

說明:變量 v_hpone_num既用來向存儲過程傳遞舊電話號碼,也用來向主程序返回新號碼。新的

號碼在原來基礎上增加了區號 0755-

創建和刪除存儲函數

 

 

創建函數,需要有 create procedure create any procedure的系統權限。該權限可由系統管理員授

予。創建存儲函數的語法和創建存儲過程的類似,即

create [or replace] function函數名[(參數[in]數據類型…)]

return數據類型

{as|is}

[說明部分]

begin


 

 

 

 

 

 

 

可執行部分

return (表達式)

[exception

錯誤處理部分]

end [函數名];

 

其中,參數是可選的,但只能是 in類型(in關鍵字可以省略)

在定義部分的 return數據類型,用來表示函數的數據類型,也就是返回值的類型,此部分不可省

略。在可執行部分的 return(表達式),用來生成函數的返回值,其表達式的類型應該和定義部分說

明的函數返回值的數據類型一致。在函數的執行部分可以有多個 return語句,但只有一個 return

語句會被執行,一旦執行了 return語句,則函數結束並返回調用環境。

一個存儲函數在不需要時可以刪除,但刪除的人應是函數的創建者或者是擁有 drop any procedure

系統權限的人。其語法如下:

drop function函數名;

重新編譯一個存儲函數時,編譯的人應是函數的創建者或者擁有 alter any procedure系統權限

的人。重新編譯一個存儲函數的語法如下:

alter procedure函數名 compile

函數的調用者應是函數的創建者或擁有 execute any procedure系統權限的人,或是被函數的擁

有者授予了函數執行權限的賬戶。函數的引用和存儲過程不同,函數要出現在程序體中,可以參加

表達式的運算或單獨出現在表達式中,其形式如下:

變量名:=函數名(…)


【訓練 1

 

創建一個通過雇員編號返回雇員名稱的函數 get_emp_name

 

步驟 1:登錄 scott賬戶。

步驟 2:在 sql*plus輸入區中輸入以下存儲函數並編譯:

sql代碼

create or replace function get_emp_name(p_empno number default 7788)

return varchar2

as

v_ename varchar2(10);

begin

elect ename into v_ename from emp where empno=p_empno;

return(v_ename);

exception

when no_data_found then

dbms_output.put_line(‘沒有該編號雇員‘);

return (null);

when too_many_rows then

dbms_output.put_line(‘有重復雇員編號!‘);

return (null);

when others then

dbms_output.put_line(‘發生其他錯誤!‘);

return (null);

end;


 

 

 

 

 

 

 

步驟 3:調用該存儲函數,輸入並執行以下程序:

sql代碼

begin

dbms_output.put_line(‘雇員 7369的名稱是:‘|| get_emp_name(7369));

dbms_output.put_line(‘雇員 7839的名稱是:‘|| get_emp_name(7839));

end;

 

顯示結果為:

sql代碼

雇員 7369的名稱是:smith

雇員 7839的名稱是:king

pl/sql過程已成功完成。

 

說明:函數的調用直接出現在程序的 dbms_output.put_line語句中,作為字符串表達式的一部分。

如果輸入了錯誤的雇員編號,就會在函數的錯誤處理部分輸出錯誤信息。試修改雇員編號,重新運

行調用部分。

【練習 1】創建一個通過部門編號返回部門名稱的存儲函數 get_dept_name

【練習 2】將函數的執行權限授予 student賬戶,然后登錄 student賬戶調用。

存儲過程和函數的查看可以通過對數據字典的訪問來查詢存儲過程或函數的有關信息,如果要查詢

當前用戶的存儲過程或函數的源代碼,可以通過對

user_source數據字典視圖的查詢得到。user_source的結構如下:

sql代碼

describe user_source

 

結果為:

sql代碼

 

名稱

 

是否為空?類型

 

————————————————————- ————- ———————–

name varchar2(30)

type varchar2(12)

line number

text varchar2(4000)

 

說明:里面按行存放着過程或函數的腳本,name是過程或函數名,type代表類型(procedure

function)line是行號,text為腳本。

 

 

【訓練 1

 

 

查詢過程 emp_count的腳本。

 

sql*plus中輸入並執行如下查詢:

sql代碼

select text from user_source where name=’emp_count’;

結果為:

sql代碼

text

——————————————————————————–


 

 

 

 

 

 

 

procedure emp_count(p_total out number)

as

begin

select count(*) into p_total from emp;

end;


【訓練 2

 

查詢過程 get_emp_name的參數。

 

sql*plus中輸入並執行如下查詢:

sql代碼

describe get_emp_name

結果為:

sql代碼

function get_emp_name returns varchar2


參數名稱

 

類型

 

輸入/輸出默認值?

 

——– ——- ——————–

p_empno  number(4) in default


 

【訓練 3

 

 

在發生編譯錯誤時,顯示錯誤。

 

sql代碼

show errors

以下是一段編譯錯誤顯示:

sql代碼

line/col error

———- ——————-  ————–

4/2 pl/sql: sql statement ignored

4/36     pls-00201:必須說明標識符 ‘empp’

 

說明:查詢一個存儲過程或函數是否是有效狀態(即編譯成功),可以使用數據字典 user_objects

status列。

【訓練 4】查詢 emp_list存儲過程是否可用:

sql代碼

select status from user_objects where object_name=’emp_list’;

 

結果為:

sql代碼

status

————

valid

說明:valid表示該存儲過程有效(即通過編譯)invalid表示存儲過程無效或需要重新編譯。當 oracle

調用一個無效的存儲過程或函數時,首先試圖對其進行編譯,如果編譯成功則將狀態置成 valid

執行,否則給出錯誤信息。當一個存儲過程編譯成功,狀態變為 valid,會不會在某些情況下變成

invalid。結論是完全可能的。比如一個存儲過程中包含對表的查詢,如果表被修改或刪除,存儲過

程就會變成無效 invalid。所以要注意存儲過程和函數對其他對象的依賴關系。

如果要檢查存儲過程或函數的依賴性,可以通過查詢數據字典 user_denpendencies來確定,該表結

構如下:

 

 

 

 

 

 

 

 

sql代碼

describe user_dependencies;

結果:

sql代碼

 

名稱

 

是否為空

 

類型

 

—– ———-    ————

name   not null      varchar2(30)

type                varchar2(12)

referenced_owner      varchar2(30)

referenced_name       varchar2(64)

referenced_type       varchar2(12)

referenced_link_name  varchar2(128)

schemaid             number

dependency_type       varchar2(4)

 

說明: name為實體名, type為實體類型, referenced_owner為涉及到的實體擁有者賬戶,

referenced_name為涉及到的實體名,referenced_type為涉及到的實體類型。

 

【訓練 5

 

查詢 emp_list存儲過程的依賴性。

 

sql代碼

select referenced_name,referenced_type from user_dependencies where name=’emp_list’;

執行結果:

sql代碼

referenced_name                     referenced_type

—————————— —————————

standard                            package

sys_stub_for_purity_analysis   package

dbms_output                 package

dbms_output                 synonym

dbms_output       non-existent

emp         table

emp_count    procedure

 

說明:可以看出存儲過程 emp_list依賴一些系統包、emp表和 emp_count存儲過程。如果刪除

emp表或 emp_count存儲過程,emp_list將變成無效。還有一種情況需要我們注意:如果一個

用戶 a被授予執行屬於用戶 b的一個存儲過程的權限,在用戶 b的存儲過程中,訪問到用戶 c的表,

用戶 b被授予訪問用戶 c的表的權限,但用戶 a沒有被授予訪問用戶 c表的權限,那么用戶 a調用

用戶 b的存儲過程是失敗的還是成功的呢?答案是成功的。如果讀者有興趣,不妨進行一下實際測

試。

 

 

 

2、程序包

 

 

包的概念和組成

包是用來存儲相關程序結構的對象,它存儲於數據字典中。包由兩個分離的部分組成:包頭(package)


 

 

 

 

 

 

 

和包體(package body)。包頭是包的說明部分,是對外的操作接口,對應用是可見的;包體是包的

代碼和實現部分,對應用來說是不可見的黑盒。

包中可以包含的程序結構如下所示。

sql代碼

 

過程(procudure)

函數(function)

變量(variable)

常量(constant)

 

帶參數的命名的程序模塊

帶參數、具有返回值的命名的程序模塊

存儲變化的量的存儲單元

存儲不變的量的存儲單元

 

游標(cursor)用戶定義的數據操作緩存區,在可執行部分使用

 

類型(type)

 

用戶定義的新的結構類型

 

異常(exception)

 

在標准包中定義或由用戶自定義,用於處理程序錯誤

 

 

說明部分可以出現在包的三個不同的部分:出現在包頭中的稱為公有元素,出現在包體中的稱

為私有元素,出現在包體的過程(或函數)中的稱為局部變量。它們的性質有所不同,如下所示。

sql代碼

 

公有元素(public)

過程有效

 

在包頭中說明,在包體中具體定義在包外可見並可以訪問,對整個應用的全

 

私有元素(private)

 

在包體的說明部分說明

 

只能被包內部的其他部分訪問

 

局部變量(local)在過程或函數的說明部分說明

 

只能在定義變量的過程或函數中使用

 

 

在包體中出現的過程或函數,如果需要對外公用,就必須在包頭中說明,包頭中的說明應該和包體

中的說明一致。

包有以下優點:

*包可以方便地將存儲過程和函數組織到一起,每個包又是相互獨立的。在不同的包中,過程、函

數都可以重名,這解決了在同一個用戶環境中命名的沖突問題。

*包增強了對存儲過程和函數的安全管理,對整個包的訪問權只需一次授予。

*在同一個會話中,公用變量的值將被保留,直到會話結束。

*區分了公有過程和私有過程,包體的私有過程增加了過程和函數的保密性。

*包在被首次調用時,就作為一個整體被全部調入內存,減少了多次訪問過程或函數的 i/o次數。

創建包和包體

包由包頭和包體兩部分組成,包的創建應該先創建包頭部分,然后創建包體部分。創建、刪除和編

譯包的權限同創建、刪除和編譯存儲過程的權限相同。

創建包頭的簡要語句如下:

create [or replace] package包名

{is|as}

公有變量定義

公有類型定義

公有游標定義

公有異常定義

函數說明

過程說明

end;

 

創建包體的簡要語法如下:

 

 

 

 

 

 

 

 

create [or replace] package body包名

{is|as}

私有變量定義

私有類型定義

私有游標定義

私有異常定義

函數定義

過程定義

end;

包的其他操作命令包括:

刪除包頭:

drop package包頭名

刪除包體:

drop package body包體名

重新編譯包頭:

alter package包名 compile package

重新編譯包體:

alter package包名 compile package body

在包頭中說明的對象可以在包外調用,調用的方法和調用單獨的過程或函數的方法基本相同,

惟一的區別就是要在調用的過程或函數名前加上包的名字(中間用“.”分隔)。但要注意,不同的會話

將單獨對包的公用變量進行初始化,所以不同的會話對包的調用屬於不同的應用。

系統包 oracle預定義了很多標准的系統包,這些包可以在應用中直接使用,比如在訓練中我們使

用的 dbms_output包,就是系統包。put_line是該包的一個函數。常用系統包下所示。

sql代碼

dbms_output sql*plus環境下輸出信息

 

dbms_ddl

dbms_session

 

編譯過程函數和包

改變用戶的會話,初始化包等

 

dbms_transaction

 

控制數據庫事務

 

dbms_mail

dbms_lock

dbms_alert

dbms_pipe

dbms_job

dbms_lob

dbms_sql

 

連接 oracle*mail

進行復雜的鎖機制管理

識別數據庫事件告警

通過管道在會話間傳遞信息

管理 oracle的作業

操縱大對象

執行動態 sql語句

 

 

dbms_output sql*plus環境下輸出信息

 

dbms_ddl

 

編譯過程函數和包

 

dbms_session改變用戶的會話,初始化包等

dbms_transaction控制數據庫事務

 

dbms_mail

dbms_lock

dbms_alert

dbms_pipe

 

連接 oracle*mail

進行復雜的鎖機制管理

識別數據庫事件告警

通過管道在會話間傳遞信息

 

 

 

 

 

 

 

 

dbms_job

dbms_lob

dbms_sql


 

 

 

 

 

 

 

管理 oracle的作業

操縱大對象

執行動態 sql語句

 

包的應用

sql*plus環境下,包和包體可以分別編譯,也可以一起編譯。如果分別編譯,則要先編譯包頭,

后編譯包體。如果在一起編譯,則包頭寫在前,包體在后,中間用“/”分隔。

可以將已經存在的存儲過程或函數添加到包中,方法是去掉過程或函數創建語句的 create or

replace部分,將存儲過程或函數復制到包體中,然后重新編譯即可。

如果需要將私有過程或函數變成共有過程或函數的話,將過程或函數說明部分復制到包頭說明

部分,然后重新編譯就可以了。

【訓練 1】創建管理雇員信息的包 employe,它具有從 emp表獲得雇員信息,修改雇員名稱,修

改雇員工資和寫回 emp表的功能。

步驟 1:登錄 scott賬戶,輸入以下代碼並編譯:

sql代碼

create or replace package employe –包頭部分

is

procedure show_detail;

procedure get_employe(p_empno number);

procedure save_employe;

procedure change_name(p_newname varchar2);

procedure change_sal(p_newsal number);

end employe;

/

create or replace package body employe –包體部分

is

employe emp%rowtype;

————–顯示雇員信息 —————

procedure show_detail

as

begin

dbms_output.put_line(‘—–雇員信息 —–’);

dbms_output.put_line(‘雇員編號:‘||employe.empno);

dbms_output.put_line(‘雇員名稱:‘||employe.ename);

dbms_output.put_line(‘雇員職務:‘||employe.job);

dbms_output.put_line(‘雇員工資:‘||employe.sal);

dbms_output.put_line(‘部門編號:‘||employe.deptno);

end show_detail;

—————– emp表取得一個雇員 ——————–

procedure get_employe(p_empno number)

as

begin

select * into employe from emp where   empno=p_empno;

dbms_output.put_line(‘獲取雇員‘||employe.ename||’信息成功‘);

exception


 

 

 

 

 

 

 

when others then

dbms_output.put_line(‘獲取雇員信息發生錯誤!‘);

end get_employe;

———————-保存雇員到 emp ————————–

procedure save_employe

as

begin

update emp set ename=employe.ename, sal=employe.sal where empno=

employe.empno;

dbms_output.put_line(‘雇員信息保存完成!‘);

end save_employe;

—————————-修改雇員名稱 ——————————

procedure change_name(p_newname varchar2)

as

begin

employe.ename:=p_newname;

dbms_output.put_line(‘修改名稱完成!‘);

end change_name;

—————————-修改雇員工資 ————————–

procedure change_sal(p_newsal number)

as

begin

employe.sal:=p_newsal;

dbms_output.put_line(‘修改工資完成!‘);

end change_sal;

end employe;

 

create or replace package employe –包頭部分

is

procedure show_detail;

procedure get_employe(p_empno number);

procedure save_employe;

procedure change_name(p_newname varchar2);

procedure change_sal(p_newsal number);

end employe;

/

create or replace package body employe –包體部分

is

employe emp%rowtype;

————–顯示雇員信息 —————

procedure show_detail

as

begin

dbms_output.put_line(‘—–雇員信息 —–’);


 

 

 

 

 

 

 

dbms_output.put_line(‘雇員編號:‘||employe.empno);

dbms_output.put_line(‘雇員名稱:‘||employe.ename);

dbms_output.put_line(‘雇員職務:‘||employe.job);

dbms_output.put_line(‘雇員工資:‘||employe.sal);

dbms_output.put_line(‘部門編號:‘||employe.deptno);

end show_detail;

—————– emp表取得一個雇員 ——————–

procedure get_employe(p_empno number)

as

begin

select * into employe from emp where   empno=p_empno;

dbms_output.put_line(‘獲取雇員‘||employe.ename||’信息成功‘);

exception

when others then

dbms_output.put_line(‘獲取雇員信息發生錯誤!‘);

end get_employe;

———————-保存雇員到 emp ————————–

procedure save_employe

as

begin

update emp set ename=employe.ename, sal=employe.sal where empno=

employe.empno;

dbms_output.put_line(‘雇員信息保存完成!‘);

end save_employe;

—————————-修改雇員名稱 ——————————

procedure change_name(p_newname varchar2)

as

begin

employe.ename:=p_newname;

dbms_output.put_line(‘修改名稱完成!‘);

end change_name;

—————————-修改雇員工資 ————————–

procedure change_sal(p_newsal number)

as

begin

employe.sal:=p_newsal;

dbms_output.put_line(‘修改工資完成!‘);

end change_sal;

end employe;

步驟 2:獲取雇員 7788的信息:

sql代碼

set serveroutput on

execute employe.get_employe(7788);

結果為:

 

 

 

 

 

 

 

 

sql代碼

獲取雇員 scott信息成功

pl/sql過程已成功完成。

 

步驟 3:顯示雇員信息:

sql代碼

execute employe.show_detail;

結果為:

sql代碼

——————雇員信息 ——————

雇員編號:7788

雇員名稱:scott

雇員職務:analyst

雇員工資:3000

部門編號:20

pl/sql過程已成功完成。

步驟 4:修改雇員工資:

sql代碼

execute employe.change_sal(3800);

 

結果為:

sql代碼

修改工資完成!

pl/sql過程已成功完成。

步驟 5:將修改的雇員信息存入 emp

sql代碼

execute employe.save_employe;

 

結果為:

sql代碼

雇員信息保存完成!

pl/sql過程已成功完成。

 

說明:該包完成將 emp表中的某個雇員的信息取入內存記錄變量,在記錄變量中進行修改編輯,

在確認顯示信息正確后寫回 emp表的功能。記錄變量 employe用來存儲取得的雇員信息,定義為

私有變量,只能被包的內部模塊訪問。

【練習 1】為包增加修改雇員職務和部門編號的功能。

階段訓練

下面的訓練通過定義和創建完整的包 emp_pk並綜合運用本章的知識,完成對雇員表的插入、刪除

等功能,包中的主要元素解釋如下所示。

sql代碼

 

程序結構

 

類型說明

 

v_emp_count公有變量

 

跟蹤雇員的總人數變化,插入、刪除雇員的同時修改該變量的值

 

init

 

公有過程

 

對包進行初始化,初始化雇員人數和工資修改的上、下限

 

 

 

 

 

 

 

 

list_emp

insert_emp


 

 

 

 

 

 

 

公有過程

公有過程

 

 

 

 

 

 

 

 

顯示雇員列表

通過編號插入新雇員

 

delete_emp公有過程

 

通過編號刪除雇員

 

change_emp_sal

 

公有過程

 

通過編號修改雇員工資

 

v_message

c_max_sal

c_min_sal

 

私有變量

私有變量

私有變量

 

存放准備輸出的信息

對工資修改的上限

對工資修改的下限

 

show_message

 

私有過程

 

顯示私有變量 v_message中的信息

 

exist_emp

 

私有函數

 

判斷某個編號的雇員是否存在,該函數被 insert_empdelete_emp

 

change_emp_sal等過程調用

 

 

【訓練 1

 

 

完整的雇員包 emp_pk的創建和應用。

 

步驟 1:在 sql*plus中登錄 scott賬戶,輸入以下包頭和包體部分,按執行按鈕編譯:

 

 

create or replace package emp_pk

包頭部分

is

v_emp_count number(5);

雇員人數

procedure init(p_max number,p_min number); –初始化

procedure list_emp;

顯示雇員列表

procedure insert_emp(p_empno number,p_enamevarchar2,p_job varchar2,

p_sal number);

插入雇員

procedure delete_emp(p_empno number);      –刪除雇員

procedure change_emp_sal(p_empno number,p_sal number);

修改雇員工資

end emp_pk;

/create or replace package body emp_pk

包體部分

is

v_message varchar2(50); –顯示信息

v_max_sal number(7); –工資上限

v_min_sal number(7); –工資下限

function exist_emp(p_empno number) return boolean; –判斷雇員是否存在函數

procedure show_message; –顯示信息過程

——————————-初始化過程 —————————-

procedure init(p_max number,p_min number)

is

begin

select count(*) into v_emp_count from emp;

v_max_sal:=p_max;

v_min_sal:=p_min;


 

 

 

 

 

 

 

v_message:=’初始化過程已經完成!‘;

show_message;

end init;

—————————-顯示雇員列表過程 ———————

procedure list_emp

is

begin


dbms_output.put_line(‘姓名

 

職務

 

工資‘);


for emp_rec in (select * from emp)

loop

dbms_output.put_line(rpad(emp_rec.ename,10,”)||rpad(emp_rec.job,10,’

‘)||to_char(emp_rec.sal));

end loop;

dbms_output.put_line(‘雇員總人數‘||v_emp_count);

end list_emp;

—————————–插入雇員過程 —————————–


procedureinsert_emp(p_empno

 

number,p_enamevarchar2,p_job varchar2,p_sal number)


is

begin

if not exist_emp(p_empno) then


insert into emp(empno,ename,job,sal)

commit;

v_emp_count:=v_emp_count+1;

v_message:=’雇員‘||p_empno||’已插入!’;

else

v_message:=’雇員‘||p_empno||’已存在,不能插入!’;

end if;

show_message;

exception

when others then

v_message:=’雇員‘||p_empno||’插入失敗!’;

show_message;

end insert_emp;

—————————刪除雇員過程 ——————–

procedure delete_emp(p_empno number)

is

begin

if exist_emp(p_empno) then

delete from emp where empno=p_empno;

commit;

v_emp_count:=v_emp_count-1;

v_message:=’雇員‘||p_empno||’已刪除!’;

else

v_message:=’雇員‘||p_empno||’不存在,不能刪除!’;

 

values(p_empno,p_ename,p_job,p_sal);


 

 

 

 

 

 

 

end if;

show_message;

exception

when others then

v_message:=’雇員‘||p_empno||’刪除失敗!’;

show_message;

end delete_emp;

—————————————修改雇員工資過程 ————————————

procedure change_emp_sal(p_empno number,p_sal number)

is

begin

if (p_sal>v_max_sal or p_sal<v_min_sal) then

v_message:=’工資超出修改范圍!’;

elsif not exist_emp(p_empno) then

v_message:=’雇員‘||p_empno||’不存在,不能修改工資!’;

else

update emp set sal=p_sal where empno=p_empno;

commit;

v_message:=’雇員‘||p_empno||’工資已經修改!’;

end if;

show_message;

exception

when others then

v_message:=’雇員‘||p_empno||’工資修改失敗!’;

show_message;

end change_emp_sal;

—————————-顯示信息過程 —————————-

procedure show_message

is

begin

dbms_output.put_line(‘提示信息:‘||v_message);

end show_message;

————————判斷雇員是否存在函數 ——————-

function exist_emp(p_empno number)

return boolean

is

v_num number; –局部變量

begin

select count(*) into v_num from emp where empno=p_empno;

if v_num=1 then

return true;

else

return false;

end if;


 

 

 

 

 

 

 

end exist_emp;

—————————–

end emp_pk;

 

結果為:

sql代碼

程序包已創建。

程序包主體已創建。

步驟 2:初始化包:

sql代碼

set serveroutput on

execute emp_pk.init(6000,600);

 

顯示為:

sql代碼

提示信息:初始化過程已經完成!

 

 

步驟 3:顯示雇員列表:

sql代碼

execute emp_pk.list_emp;

 

顯示為:

sql代碼

 

姓名

 

職務

 

工資

 

smith      clerk      1560

allen      salesman   1936

ward       salesman   1830

jones      manager    2975

雇員總人數:14

 

步驟 4:插入一個新記錄:

sql代碼

execute emp_pk.insert_emp(8001,’小王‘,’clerk’,1000);

 

顯示結果為:

sql代碼

提示信息:雇員 8001已插入!

pl/sql過程已成功完成。

 

步驟 5:通過全局變量 v_emp_count查看雇員人數:

sql代碼

begin

dbms_output.put_line(emp_pk.v_emp_count);


 

 

 

 

 

 

 

end;

 

顯示結果為:

sql代碼

15

pl/sql過程已成功完成。

 

步驟 6:刪除新插入記錄:

sql代碼

execute emp_pk.delete_emp(8001);

 

顯示結果為:

sql代碼

提示信息:雇員 8001已刪除!

pl/sql過程已成功完成。

 

再次刪除該雇員:

sql代碼

execute emp_pk.delete_emp(8001);

 

結果為:

sql代碼

提示信息:雇員 8001不存在,不能刪除!

 

步驟 7:修改雇員工資:

sql代碼

execute emp_pk.change_emp_sal(7788,8000);

 

顯示結果為:

sql代碼

提示信息:工資超出修改范圍!

pl/sql過程已成功完成。

步驟 8:授權其他用戶調用包:

如果是另外一個用戶要使用該包,必須由包的所有者授權,下面授予 studen賬戶對該包的使用

權:

sql代碼

grant execute on emp_pk to student;

每一個新的會話要為包中的公用變量開辟新的存儲空間,所以需要重新執行初始化過程。兩個會

話的進程互不影響。

步驟 9:其他用戶調用包。

啟動另外一個 sql*plus,登錄 student賬戶,執行以下過程:

sql代碼

set serveroutput on

execute scott.emp_pk. emp_pk.init(5000,700);


 

 

 

 

 

 

 

結果為:

sql代碼

提示信息:初始化過程已經完成!

pl/sql過程已成功完成。

說明:在初始化中設置雇員的總人數和修改工資的上、下限,初始化后 v_emp_count 14人,

插入雇員后 v_emp_count 15人。v_emp_count為公有變量,所以可以在外部程序中使用

dbms_output.put_line輸出,引用時用 emp_pk.v_emp_count的形式,說明所屬的包。

而私有變量 v_max_sal v_min_sal不能被外部訪問,只能通過內部過程來修改。

同樣,exist_emp show_message也是私有過程,也只能在過程體內被其他模塊引用。

注意:在最后一個步驟中,因為 student模式調用了 scott模式的包,所以包名前要增加

模式名 scott。不同的會話對包的調用屬於不同的應用,所以需要重新進行初始化。

 

 

 

3、操作練習

 

 

1)如果存儲過程的參數類型為 out,那么調用時傳遞的參數應該為:

 

a.常量 b.表達式

 

c.變量 d.都可以

 

2)下列有關存儲過程的特點說法錯誤的是:

a.存儲過程不能將值傳回調用的主程序

b.存儲過程是一個命名的模塊

c.編譯的存儲過程存放在數據庫中

d.一個存儲過程可以調用另一個存儲過程

3)下列有關函數的特點說法錯誤的是:

a.函數必須定義返回類型

b.函數參數的類型只能是 in

c.在函數體內可以多次使用 return語句

d.函數的調用應使用 execute命令

4)包中不能包含的元素為:

a.存儲過程 b.存儲函數

 

c.游標

 

d.表

 

5)下列有關包的使用說法錯誤的是:

a.在不同的包內模塊可以重名

b.包的私有過程不能被外部程序調用

c.包體中的過程和函數必須在包頭部分說明

d.必須先創建包頭,然后創建包體

 

 

 

4、觸發器

 

 

觸發器:是特定事件出現的時候,自動執行的代碼塊。類似於存儲過程,但是用戶不能直接調用

他們,其功能如下:

1)允許/限制對表的修改

2)自動生成派生列,比如自增字段

 

 

 

 

 

 

 

 

3)強制數據一致性

4)提供審計和日志記錄

5)防止無效的事務處理

6)啟用復雜的業務邏輯

 

開始

create trigger biufer_employees_department_id

before insert or update

of department_id

on employees

referencing old as old_value

new as new_value

for each row

when (new_value.department_id<>80 )

begin

:new_value.commission_pct :=0;

end;

/

觸發器的組成部分:的

 

 

 

1)觸發器名稱

2)觸發語句

3)觸發器限制

4)觸發操作

 

觸發器名稱:

create trigger biufer_employees_department_id

 

命名習慣:

biuferbefore insert update for each row

employees表名

department_id列名

 

觸發語句

比如:

表或視圖上的 dml語句

ddl語句

數據庫關閉或啟動,startup shutdown等等

 

 

before insert or update

of department_id

on employees

referencing old as old_value


 

 

 

 

 

 

 

new as new_value

for each row

說明:

 

 

1)無論是否規定了 department_id,對 employees表進行 insert的時候

2)對 employees表的 department_id列進行 update的時候

3)觸發器限制

 

 

when (new_value.department_id<>80 )

限制不是必須的。此例表示如果列 department_id不等於 80的時候,觸發器就會執行。

其中的 new_value是代表更新之后的值。

 

觸發操作:

是觸發器的主體

begin

:new_value.commission_pct :=0;

end;

主體很簡單,就是將更新后的 commission_pct列置為 0

 

觸發:

insert into employees(employee_id,

last_name,first_name,hire_date,job_id,email,department_id,salary,commission_pct )

values( 12345,’chen’,’donny’, sysdate, 12, ‘donny@hotmail.com’,60,10000,.25);

select commission_pct from employees where employee_id=12345;

觸發器不會通知用戶,便改變了用戶的輸入值。

 

 

觸發器類型:

1)語句觸發器

2)行觸發器

3 instead of觸發器

4)系統條件觸發器

5)用戶事件觸發器

 

 

 

5Job創建和操作

 

 

1)設置初始化參數 job_queue_processes

alter system set job_queue_processes=n;n>0job_queue_processes最大值為 1000

查看 job queue后台進程

select name,description from v$bgprocess;

 

2)dbms_job package用法介紹

包含以下子過程:

broken()過程;change()過程;interval()過程;isubmit()過程;next_date()過程;


 

 

 

 

 

 

 

remove()過程;run()過程;submit()過程;user_export()過程;what()過程;

 

(1)broken()過程更新一個已提交的工作的狀態,典型地是用來把一個已破工作標記為未破工作。

這個過程有三個參數:jobbroken next_date

procedure broken (job in binary_integer,broken in boolean,next_date in date :=sysdate)

job參數是工作號,它在問題中唯一標識工作。

broken參數指示此工作是否將標記為破——true說明此工作將標記為破,而 flase說明此工作

將標記為未破。

next_date參數指示在什么時候此工作將再次運行。此參數缺省值為當前日期和時間。

job如果由於某種原因未能成功之行,oracle將重試 16次后,還未能成功執行,將被標記為

broken重新啟動狀態為 broken job,有如下兩種方式;

a、利用 dbms_job.run()立即執行該 job

begin

dbms_job.run(:jobno) jobno submit過程提交時返回的 job number

end;

/

b、利用 dbms_job.broken()重新將 broken標記為 false

begin

dbms_job.broken (:job,false,next_date)

end;

/

(2) change()過程用來改變指定工作的設置。

這個過程有四個參數:jobwhatnext_date interval

procedure change (job in binary_integer,

what in varchar2,

next_date in date,

interval in varchar2)

job參數是一個整數值,它唯一標識此工作。

what參數是由此工作運行的一塊 pl/sql代碼塊。

next_date參數指示何時此工作將被執行。

interval參數指示一個工作重執行的頻度.

 

(3)interval()過程用來顯式地設置重執行一個工作之間的時間間隔數。這個過程有兩個參數:job

interval

procedure interval (job in binary_integer,interval in varchar2)

job參數標識一個特定的工作。interval參數指示一個工作重執行的頻度。

 

(4) isubmit()過程用來用特定的工作號提交一個工作。這個過程有五個參數:jobwhatnext_date

interval no_parse

procedure isubmit (job in binary_ineger,

what in varchar2,

next_date in date,

interval in varchar2,

no_parse in booean:=false)


 

 

 

 

 

 

 

這個過程與 submit()過程的唯一區別在於此 job參數作為 in型參數傳遞且包括一個由開發者提

供的工作號。如果提供的工作號已被使用,將產生一個錯誤。

 

 

(5)next_date()過程用來顯式地設定一個工作的執行時間。這個過程接收兩個參數:job next_date

procedure next_date(job in binary_ineger,next_date in date)

job標識一個已存在的工作。next_date參數指示了此工作應被執行的日期與時間。

 

(6)remove()過程來刪除一個已計划運行的工作。這個過程接收一個參數:

 

procedure remove(job in

 

binary_ineger);


job參數唯一地標識一個工作。這個參數的值是由為此工作調用 submit()過程返回的 job參數

的值。已正在運行的工作不能由調用過程序刪除。

 

 

(7)run()過程用來立即執行一個指定的工作。這個過程只接收一個參數:

procedure run(job in binary_ineger)

job參數標識將被立即執行的工作。

 

(8)使用 submit()過程,工作被正常地計划好。

這個過程有五個參數:jobwhatnext_dateinterval no_parse

procedure submit ( job out binary_ineger,

what in varchar2,


next_date in

interval in

no_parse in

 

date,

varchar2,

booean:=false)


job參數是由 submit()過程返回的 binary_ineger。這個值用來唯一標識一個工作。

what參數是將被執行的 pl/sql代碼塊。

next_date參數指識何時將運行這個工作。

interval參數何時這個工作將被重執行。

no_parse參數指示此工作在提交時或執行時是否應進行語法分析——true指示此 pl/sql代碼在

它第一次執行時應進行語法分析,而 false指示本 pl/sql代碼應立即進行語法分析。

 

(9)user_export()過程返回一個命令,此命令用來安排一個存在的工作以便此工作能重新提交,此程序

有兩個參數:job my_call

procedure user_export(job in binary_ineger,my_call in out varchar2)

job參數標識一個安排了的工作。my_call參數包含在它的當前狀態重新提交此工作所需要的

正文。

 

 

(10)what()過程應許在工作執行時重新設置此正在運行的命令。這個過程接收兩個參數:job what


 

 

procedure what (job


 

 

in binary_ineger, what in out varchar2)


—job參數標識一個存在的工作。what參數指示將被執行的新的 pl/sql代碼。

 

3)查看相關 job信息

 

(1)相關視圖

 

 

 

 

 

 

 

 

dba_jobs

all_jobs

user_jobs

dba_jobs_running包含正在運行 job相關信息

 

(2)查看相關信息

 

 

select job, next_date, next_sec, failures, broken

from dba_jobs;

 

 

job next_date next_sec failures b

——- ——— ——– ——– -

9125 01-jun-01 00:00:00 4 n

14144 24-oct-01 16:35:35 0 n

9127 01-jun-01 00:00:00 16 y

3 rows selected.

 

正在運行的 job相關信息

 

 

select sid, r.job, log_user, r.this_date, r.this_sec

from dba_jobs_running r, dba_jobs j

where r.job = j.job;

 

 

sid job log_user this_date this_sec

—– ———- ————- ——— ——–

12 14144 hr 24-oct-94 17:21:24

25 8536 qs 24-oct-94 16:45:12

2 rows selected.

 

job queue lock相關信息

 

 

select sid, type, id1, id2

from v$lock

where type = ‘jq’;

 

 

sid ty id1 id2

——— — ——— ———

12 jq 0 14144

1 row selected.

 

4)實例操作

創建測試表

create table test(a date);

——create table


 

 

 

 

 

 

 

創建一個自定義過程

create or replace procedure myproc as

begin

insert into test values(sysdate);

end;

/

————–過程已創建。

創建 job

variable job1 number;

begin


dbms_job.submit(:job1,’myproc;’,sysdate,’sysdate+1/1440′);

運行 test過程一次

end;

/

pl/sql過程已成功完成。

運行 job

begin

dbms_job.run(:job1);

end;

/

 

pl/sql過程已成功完成。

 

sql> select to_char(a,’yyyy/mm/dd hh24:mi:ss’)時間 from test;

 

時間

——————-

2001/01/07 23:51:21

2001/01/07 23:52:22

2001/01/07 23:53:24

 

刪除 job

begin

dbms_job.remove(:job1);

end;

/

 

 

6、后台腳本

 

 

編輯文件:dyk_name_mtable1.sql寫入以下內容:

alter table owner.table_name1 move tablespace tablespace_name1;

alter table owner.table_name2 move tablespace tablespace_name2;

 

編輯文件 dyk_name_mtable1.sh

 

每天 1440分鍾,即一分鍾

 

 

 

 

 

 

 

 

sqlplus username/passwdString @TNSstring <<!>>dyk_name_mtable2.out

@ dyk_name_mtable1.sql

!

執行命令:

Nohup dyk_name_mtable1.sh &


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM