Oracle 10g 中關(guān)于 SQL*Plus 的改進(jìn)
2024-08-29 13:37:37
供稿:網(wǎng)友
 
             
  隨著 Oracle Database 10g的發(fā)布,這個(gè)小而強(qiáng)大的 DBA 工具有了一些引人注目的變化,包括有用的提示符和高級(jí)文件處理 
  
  數(shù)據(jù)庫治理員天天用得最多的工具是哪一個(gè)?對(duì)于許多象我一樣在 GUI 革命之前的數(shù)據(jù)庫治理員而言,一定是 SQL*Plus 命令行選件。 
                                                                                              
  雖然隨著強(qiáng)大和功能豐富的 EnterPRise Manager 10g 的引入,SQL*Plus 在 Oracle Database 10g 中已經(jīng)發(fā)生了一些變化,但這個(gè)普遍存在的小工具仍將繼續(xù)作為 Oracle 原有系統(tǒng)的一部分 — 對(duì)初學(xué)者和經(jīng)驗(yàn)豐富的數(shù)據(jù)庫治理員同樣適用。 
  
  在本部分中,我們將研究對(duì) SQL*Plus 10.1.0.2 所作的一些非常有用的改進(jìn)。切記,要繼續(xù)下面的操作,您將需要 Oracle Database 10g 軟件的 sqlplus 可執(zhí)行程序,而不是運(yùn)行在 10g 數(shù)據(jù)庫上的 Oracle9i Database sqlpuls。 
  
  為粗心用戶提供的提示符 
  我在哪里,或我是誰?不,這不是對(duì)您精神的拷問;這是關(guān)于用戶在 SQL*Plus 環(huán)境的上下文中位于何處的問題。SQL*Plus 中的默認(rèn)提示符 — 簡(jiǎn)單的 SQL> — 不指出用戶是誰,以及用戶作為什么連接。在早期的版本中,您必須進(jìn)行一些麻煩的編碼來獲取變量,但現(xiàn)在不再需要這樣了。在 SQL*Plus 10.1.0.2 中,您可以使用: 
  
  set sqlprompt "_user _privilege> "
  
  SQL*Plus 提示符顯示為 
  
  SYS AS SYSDBA>
  
  當(dāng)然,假定用戶 SYS 是作為 SYSDBA 登錄的。注重兩個(gè)預(yù)先定義的非凡變量 — _user 和 _privilege — 的使用,它們定義了當(dāng)前的用戶和登錄的權(quán)限。 
  
  讓我們?cè)僭黾右恍┢渌墓δ埽含F(xiàn)在還想顯示今天的日期。我們需要做的就是用下面這些命令來使提示符顯示想得到的信息。 
  
  SQL> set sqlprompt "_user _privilege 'on' _date >"
  SYS AS SYSDBA on 06-JAN-04 >
  
  再增加數(shù)據(jù)庫連接標(biāo)識(shí)符怎么樣?您想知道您在“什么樣”(在生產(chǎn)或開發(fā)中)的情況下,這種方法的確非常有幫助。 
  
  SQL> set sqlprompt "_user 'on' _date 'at' _connect_identifier >"
  
  ANANDA on 06-JAN-04 at SMILEY >
  
  到目前為止還不錯(cuò);但我們可能想要以一種更具體的方式來顯示當(dāng)前的日期(帶小時(shí)和分鐘),以更加有用。 
  
  ANANDA on 06-JAN-04 at SMILEY > alter session set nls_date_format = 'mm/dd/yyyy hh24:mi:ss';
  
  Session altered.
  
  ANANDA on 01/06/2004 13:03:51 at SMILEY >
  
  問題解決了:輸入幾行命令就得到了能夠提供豐富信息的 SQL 提示符。將它保存在 glogin.sql 文件中,您就始終擁有這些特性。 
  
  必須使用引號(hào)嗎?為什么,不! 
  
  在 Oracle9i 中取消了對(duì)內(nèi)部登錄的支持之后,全世界許多 DBA 表示反對(duì):他們應(yīng)當(dāng)如何在命令行上輸入 SYS 的口令并保持安全性?嗯,答案是在操作系統(tǒng)提示符中使用引號(hào): 
  
  sqlplus "/ as sysdba"
  
  引號(hào)的使用令人遺憾,但還是被大家所接受(雖然有些怨言)。在 Oracle Database 10g 中不需要這樣了。現(xiàn)在您可以在 OS 命令提示符下,輸入以下命令,不需要引號(hào) 
  
  sqlplus / as sysdba
  
  作為 SYSDBA 登錄。這種改進(jìn)不僅意味著您少輸了兩個(gè)字符,還有一些額外的好處,例如在 Unix 之類的操作系統(tǒng)中不需要 escape 字符。 
  
  改進(jìn)的文件處理 
  假設(shè)您在處理一個(gè)問題,并使用了一些自由格式的即席 SQL 語句。很明顯,它們很有用,您想把它們保存起來,以便將來使用。您會(huì)怎么做?您就可以把它們保存在各個(gè)文件中,如下所示: 
  
  select something1 ....
  save 1 
  select something else ....
  save 2
  select yet another thing ....
  save 3 
  
  等等。一段時(shí)間以后,您需要收集所有保存的文件,以便將來使用。多麻煩!SQL*Plus 10.1.0.2 答應(yīng)您將語句添加到文件中,進(jìn)行保存。在前一個(gè)例子中,您可以使用: 
  
  select something1 ....
  save myscripts
  select something else ....
  save myscripts append
  select yet another thing ....
  save myscripts append
  
  等等。
                         所有的語句將添加到文件 myscripts.sql 中,從而不再需要保存在單獨(dú)的文件中,然后把它們連接成單個(gè)文件。 
  
  這種方法還適用于假脫機(jī)。在以前的版本中,命令 SPOOL RESULT.LST 將創(chuàng)建文件 result.lst (假如該文件不存在);但假如該文件已存在,則將覆蓋它,而沒有提示。這種行為經(jīng)常(非凡在復(fù)雜環(huán)境下)可能導(dǎo)致不希望的邊緣效應(yīng),例如重要的輸出文件被覆蓋。在 10g 中,spool 命令可以使文件內(nèi)容附加在一個(gè)現(xiàn)有的文件后面: 
  
  spool result.lst append
  
  假如您想覆蓋它,那么該怎么做?簡(jiǎn)單地省略 append 子句,或使用默認(rèn)值 REPLACE。以下命令將在寫操作之前檢查文件是否存在。 
  
  spool result.lst create
  Use another name or "SPOOL filename[.ext] REPLACE"
  
  這種方法防止覆蓋文件 result.lst。 
  
  Login.sql 是用于登錄的,是嗎? 
  
  記得文件 login.sql 和 glogin.sql 嗎?本來在任何時(shí)候當(dāng)調(diào)用 SQL*Plus 時(shí),都將運(yùn)行當(dāng)前目錄中的 login.sql 文件。但是,有一個(gè)嚴(yán)重的局限。在 Oracle9i 和更低版本中,假定在文件中有下面這一行。 
  
  set sqlprompt "_connect_identifier >"
  
  當(dāng)您首先啟動(dòng) SQL*Plus 與數(shù)據(jù)庫 DB1 連接時(shí),提示符顯示: 
  
  DB1>
  
  現(xiàn)在,假如您從提示符中與另一個(gè)數(shù)據(jù)庫 DB2 連接: 
  
  DB1> connect scott/tiger@db2
  Connected
  DB1>
  
  注重提示符。雖然您現(xiàn)在和 DB2 連接在一起,但提示符仍是 DB1,。很明顯,提示符是不正確的。原因很簡(jiǎn)單:在連接時(shí)沒有執(zhí)行 login.sql 文件,只在 SQL*Plus 啟動(dòng)時(shí)執(zhí)行了該文件。后來的連接沒有重新執(zhí)行該文件,使得提示符沒有改變。 
  
  在 Oracle Database 10g 中,消除了該局限。文件 login.sql 不僅在 SQL*Plus 啟動(dòng)時(shí)執(zhí)行,而且在連接時(shí)也執(zhí)行。因此在 10g 中,假如您當(dāng)前與數(shù)據(jù)庫 DB1 連接,后來改變了連接,則提示符將改變。 
  
  SCOTT at DB1> connect scott/tiger@db2
  SCOTT at DB2> connect john/meow@db3
  JOHN at DB3>
  
  假如由于某些原因,您不想使用這些增強(qiáng)的 SQL*Plus,那該怎么辦?很簡(jiǎn)單,用 -c 選項(xiàng)來調(diào)用它: 
  
  sqlplus -c 9.2
  
  SQL*Plus 環(huán)境將和舊的 9.2 版一樣運(yùn)轉(zhuǎn)。 
  
  自由地使用 DUAL 
  您認(rèn)為有多少開發(fā)人員(還有 DBA)經(jīng)常使用這條命令? 
  
  select USER into from DUAL
  
  可能非常多。對(duì) DUAL 的每次調(diào)用創(chuàng)建邏輯 I/O — 數(shù)據(jù)庫沒有邏輯 I/O 也可以工作。在某些情況下必須調(diào)用 DUAL,如在行 := USER 中。因?yàn)?Oracle 代碼將 DUAL 當(dāng)作一個(gè)專用的表,所以調(diào)整表的某些想法可能不適用或不貼切。 
  
  Oracle Database 10g 使得所有這些擔(dān)心完全消失了:因?yàn)?DUAL 是一個(gè)專用的表,所以持續(xù)獲得顯著地減少了,并且與從事件 10046 跟蹤中看到的優(yōu)化計(jì)劃不同。 
  
  在 Oracle9i 中 
  Rows   Execution Plan
  ------- ---------------------------------------------------
  0 SELECT STATEMENT  GOAL:CHOOSE
  1  TABLE access (FULL) OF 'DUAL'
  	 
  
  在 10g 中 
  Rows   Execution Plan
  ------- ---------------------------------------------------
  0 SELECT STATEMENT  MODE:ALL_ROWS
  0  FAST DUAL
  
  注重新的 FAST DUAL 優(yōu)化計(jì)劃的使用,與 Oracle9i 中的 DUAL 的 FULL TABLE SCAN 相反。這一改進(jìn)顯著地減少了持續(xù)讀取,從而為頻繁使用 DUAL 表的應(yīng)用程序帶來好處。 
  
  注重:從技術(shù)角度看,這些 DUAL 改進(jìn)是在 SQL 優(yōu)化器中實(shí)施的,但是,對(duì)許多用戶而言,SQL*Plus 是用于處理 SQL 的主要工具。 
  
  其它有用的信息 
  其它的 SQL*Plus 增強(qiáng)在本系列的其它地方進(jìn)行了說明。例如,我在第 5 周關(guān)于閃回表的內(nèi)容中說明了 RECYCLEBIN 的概念。 
  
  與一些流傳甚廣的傳言相反,COPY 命令仍然可用,雖然將在以后的版本中廢除。(嗯……,我們不是在 Oracle9i 中就聽到這個(gè)消息了嗎?)假如您有使用這條命令編寫的腳本,別沮喪,它不僅可用而且仍被支持。實(shí)際上,只錯(cuò)誤消息報(bào)告方面作了一點(diǎn)改進(jìn)。假如表有一個(gè) LONG 列,則 COPY 是您創(chuàng)建表的備份的唯一方式,常見的 Create Table As Select 將不能處理帶 long 數(shù)據(jù)類型的列的表。