create table accounts ( acc_no number not null, first_name varchar2(30) not null, last_name varchar2(30) not null, SSN varchar2(9) ENCRYPT USING 'AES128', acc_type varchar2(1) not null, folio_id number ENCRYPT USING 'AES128', sub_acc_type varchar2(30), acc_open_dt date not null, acc_mod_dt date, acc_mgr_id number ) 在這里,您在列 SSN 和 FOLIO_ID 上使用了 TDE,它們現在以加密方式存儲在表本身。但是,當用戶從表中選擇時,她看到以明文表示的數據,因為在檢索過程中已經完成了解密。假如磁盤被盜,則包含在表段中的信息仍然保持加密狀態。盜竊者需要表密鑰才能看到加密的值,但是要獲得表密鑰,他需要萬能密鑰,而萬能密鑰存儲在外部,因此無法獲得。
insert into acc_comm_log values ( 3, xmltype( '<CommRecord> <CommType>PHONE</CommType> <CommDate>3/10/2005</CommDate> <CommText>Dear Ms Potter</CommText> </CommRecord>') ); 現在您可以看到表中的記錄:
SQL> l 1 select acc_no, 2 XMLQuery( 3 'for $i in /CommRecord 4 where $i/CommType != "EMAIL" 5 order by $i/CommType 6 return $i/CommDate' 7 passing by value COMM_DETAILS 8 returning content) XDetails 9 from acc_comm_log 10 /
1 select t.column_value 2 from acc_comm_log a, 3 xmltable ( 4 'for $root in $date 5 where $root/CommRecord/CommType!="EMAIL" 6 return $root/CommRecord/CommDate/text()' 7 passing a.comm_details as "date" 8* ) t SQL> /
COLUMN_VALUE --------------------- 3/12/2005 3/10/2005 此示例演示了如何將常規的 SQL 語句用于 XML 查詢所返回的 XML 表。查詢按照非常結構化的 FLOWR 模式來指定命令。 XQuery 與 XMLTable 的對比
既然您已經了解了在常規 SQL 查詢中使用 XML 的兩種方法,就讓我們來看這二種方法適用的情形。
第一種方法 XQuery 答應您獲取 XMLType 形式的數據,在任何支持它的程序或應用程序中都可以將其作為 XML 來處理。在您所看到的示例中,帳戶數據的結果輸出是 XML 格式,而您可以使用任何工具(不必是關系型工具)來處理和顯示這些數據。第二種方法 XMLTable 結合了常規 SQL 和 XML 的功能。帳戶數據的結果輸出不是 XML 格式,而是關系型數據。
注重兩個案例中的源代碼都是 XML,但是 XQuery 使用 XMLType 來表示 XML 格式的數據,而 XMLTable 將其表示為關系表,可以像常規表一樣進行處理。這種功能非常適用于要輸出表的現有程序,它引入了 XML 的特性。
XML 在預先不太了解確切的數據結構的場合中非常有用。在以上示例中,根據不同模式,通信記錄也不相同。假如是電子郵件,則屬性可能是接收方的電子郵件地址、回復地址、任何復本(cc:、bcc: 等等)、消息的文本等等。假如是電話呼叫,則屬性是所呼叫的電話號碼、號碼的類型(家庭、工作、移動電話等等)、應答者、留下的語音郵件等等。假如您要設計一個包含所有可能的屬性類型的表,則它會包括很多列,并且極其冗長,造成讀取困難。但是,假如您只有一個 XMLType 列,則可以將所有內容填在那里,但仍然保持通信類型的獨特屬性。查詢仍然可以使用簡單的 SQL 接口,使應用程序的開發變得輕而易舉。 增強的 COMMIT
1 create or replace function myfunc 2 return varchar2 3 as 4 begin 5 $if $$ppval $then 6 return 'PPVAL was TRUE'; 7 $else 8 return 'PPVAL was FALSE'; 9 $end 10* end; 注重第 5 行,您已經使用預處理器指令為變量 ppval 求值。因為 ppval 是一個預處理器變量,而不是常規的 PL/SQL 變量,所以使用 $$ 標志來指定它。同樣,為了編譯器能分辨自己只需在編譯期間處理這些行,你要用非凡的 $ 標志來指定求值項,例如用 $if 代替 if。現在,利用變量 ppval 的不同值來編譯這個函數。
SQL> alter session set plsql_ccflags = 'PPVAL:TRUE';
Session altered. 現在編譯該函數并執行它。
SQL> alter function myfunc compile;
Function altered.
SQL> select myfunc from dual;
MYFUNC ------------------------------------- PPVAL was TRUE 在編譯期間 ppval 的值被設為 false。現在更改該變量的值并重新執行該函數。
SQL> alter session set plsql_ccflags = 'PPVAL:FALSE';
Session altered.
SQL> select myfunc from dual;
MYFUNC --------------------------------------------------------- PPVAL was TRUE 雖然這里 ppval 的值在會話中是 FALSE,但函數沒有采用它;而是采用了在編譯期間所設置的值。現在,重新編譯該函數并執行它。 SQL> alter function myfunc compile;
Function altered.
SQL> select myfunc from dual;
MYFUNC --------------------------------------------------- PPVAL was FALSE 在編譯期間,ppval 的值是 FALSE,而這就是所返回的值。
ERROR at line 1: ORA-20000:ORU-10027:buffer overflow, limit of 1000000 bytes ORA-06512:at "SYS.DBMS_OUTPUT", line 32 ORA-06512:at "SYS.DBMS_OUTPUT", line 97 ORA-06512:at "SYS.DBMS_OUTPUT", line 112 ORA-06512:at line 2 這是由于供給程序包 dbms_output 過去能夠處理的最大字符數量是 1 百萬字節。在 Oracle 數據庫 10g 第 2 版中,該限制已經解除:現在最大輸出數量是不封頂的。您只需通過執行以下命令,就可以將其設為“unlimited” set serveroutput on
以上語句的輸出結果如下:
SQL> show serveroutput serveroutput ON size 2000 format Word_WRAPPED 注重輸出的最大默認值過去是 2000 。在 Oracle 數據庫 10g 第 2 版中,該命令顯示以下結果:
SQL> show serveroutput serveroutput ON SIZE UNLIMITED FORMAT WORD_WRAPPED 默認值是 UNLIMITED。
ERROR at line 1: ORA-20000:ORU-10028:line length overflow, limit of 255 chars per line ORA-06512:at "SYS.DBMS_OUTPUT", line 35 ORA-06512:at "SYS.DBMS_OUTPUT", line 115 ORA-06512:at line 2 在 Oracle 數據庫 10g 第 2 版中,行可以具有任意長度。