巧用SET選項提高SQL Server客戶端的靈活性

iSQlServer發表於2010-01-05

  通常情況下,利用客戶端連線到SQL Server資料庫的時候,其預設是採用伺服器的相關配置來初始化客戶端的連線。但是在某些情況下,資料庫管理員希望客戶端能夠管理自己的設定。而且往往這些客戶端的設定跟伺服器的設定不一樣,甚至相反。此時客戶端要能夠在不修改伺服器設定的情況下,連線到資料庫伺服器中。

  要實現類似的功能,就需要用到SQL Server資料庫中的SET選項。如要實現上述的需求,資料庫管理員可以把SET ANSI_DEFAULTS ON,然後再通過SQL_COPT_SS_PRESERVE_CURSORS來設定客戶端的配置。如此的話,就可以實現客戶端與伺服器配置的不同,提高客戶端配置的靈活性。

  不過需要注意的是,使用這些SET選項會導致客戶端與伺服器配置的不同,即一些連線引數、執行環境等等可能會出現混亂。為此在使用SET選項時還必須考慮這個一致性的問題。也就是說,使用SET選項時要注意如下細節,

  一、SET選項的生效時間。

  利用SET選項來設定相關的執行引數與環境的時候,要注意其生效時間。這與伺服器預設引數不同。預設引數其是始終生效的,除非後來資料庫管理員改變了其設定。但是使用SET選項來設定相關引數時,其生效時間就尤其特殊性。一般來說,SET選項可以分為分析時SET選項與執行時SET選項。隨著他們的分類不同,這個選項的生效時間也是不同的。如分析時選項在分析期間分析出文字中的選項時生效,而不管是否受流語句的控制。而執行選型則在指定這些選項的程式碼執行期間生效。如在一個批處理程式中,可以設定一個SET選項。如果在執行這個SET語句之前,批處理程式已經因為某些原因執行失敗,則這個選項就不會生效,即資料庫系統沒有設定這個選項。如果在執行SET語句後執行失敗,則這這個選項就已經生效了。

  所以說如果SET選項跟一些批處理程式一起使用時,就需要特別注意這個SET選項的位置。因為這個SET選型是否生效直接跟批處理程式中其他語句的執行情況相關。如現在一個批處理程式中有8條語句,而SET選型就是其中的一條如在第五條。如果在執行這個批處理程式的時候,在第三條語句的時候卡住了,那麼這個第五條的SET選項語句就根本不起作用。為此筆者建議資料庫管理員,像這些SET選項語句通常情況下最好放置在批處理程式的前面部分,以初始化批處理程式的相關執行環境。除非有特別的需要,否則的話不要放置在中間。

  二、要注意SET選項的作用範圍。

  其實SET選項設定的引數與資料庫伺服器的預設引數就好像是一個區域性變數與全域性變數的關係。前者設定的引數就是一個區域性變數,其只有在一個特定的範圍內有效;離開了這個範圍的話,就會失效。而全域性變數的話通常情況下都是有效的,除非在某個領域內又對其重新賦值了。所以說,資料庫管理員必須要了解SET選型的作用範圍,為後續引用這些引數做好準備。具體來說,這些SET選項,往往跟不同的功能結合使用。如跟批處理程式、跟觸發器等等結合使用。而隨著這個使用範圍的不同,其作用範圍也是不同的。

  1、在會話過程中有效。有些SET選項是專門針對客戶端連線的。如筆者剛開始提起過的那個SET選型,其就是專麼用來設定客戶端的連線引數的。這些引數可能跟伺服器的預設引數之間存在著比較大的差異。那麼這些引數的作用範圍是多少呢?通常情況下,針對專門會話所這支的SET選項,其在重置或者伺服器中使用者的會話終止之前有效。也就是說,在客戶端連線的初始化過程中SET選項生效。只要使用者的這個會話沒有終止,這些選項都是生效的。除非使用者終止了當前的會話或者伺服器強制重置相關引數,否則的話這個SET選項隨著會話啟用而生效,隨著會話終止而失效。另外需要注意的是,針對某個使用者設定的SET選項,其只對這個使用者的會話有效,而不會影響到其他使用者跟資料庫之間的通訊。

  2、支援 MARS 的連線維護一組預設的 SET 選項值。在該連線下執行批處理時,將把預設的 SET 選項值複製到請求的環境。批處理結束後,該環境將複製回會話的預設設定。通過這種方法,在同一連線下同時執行的多個批處理將在獨立的 SET 選項環境下執行。這是一個官方的說明,他是什麼意思呢?也就是說,在同一個連線的過程中,可能會執行多個批處理作業。如果在這些批處理作業中,沒有設定SET選項的話,則其預設會採用伺服器的預設設定。但是如果在第一個批處理程式中採用了SET選項更改這個預設設定,那麼在第一個批處理程式執行環境中就會採用這個SET選項的設定。從而可以根據企業實際的需求,在同一個連線下為每個批處理程式設定相對獨立的執行環境。在支援 MARS 的連線下,如果同時執行多個批處理且它們會修改批處理執行環境,則得到的預設連線環境取決於最後執行完的批處理。也就是說,最後這個連線的引數取決於最後執行的皮處理程式中的SET選項。簡單的說,除非當前的連線中斷掉或者伺服器實現強制重置,否則的話當前連線中的相關引數會被批處理程式中的SET選項改變。而且這個值會被多次改變。最後的引數是有最後一個批處理程式中的SET選項所決定。

  3、在觸發器或者過程中也可以使用SET選項。那麼跟他們結合使用時,SET選項的壽命又有多少呢?這要分情況來對待。一是要看觸發器或者過程內容有沒有多次使用SET選項。如在觸發器中,可能一開始就利用SET選項設定了某個引數;然後某個功能執行完畢後又把這個引數恢復了預設值,再繼續執行剩下的功能。在這種情況下,其有效持續時間就是觸發器內部這個引數被重置之前。也就是說,在一個觸發器或者內部可以先開啟某個選項,然後再關閉掉。那麼只有在這個選項開啟與關閉之前有效。二是如果在觸發器內部一開始啟用了某個SET選項,後來沒有把他關閉掉,那麼這個選項也不會永遠生效下去。通常情況下,只要當前這個觸發器或者過程執行完畢後,這個SET選型就會失效。為此簡單的說,這個SET選項就好象是儲存器或者過程中的區域性變數,其只在觸發器或者過程的內部生效。

  4、如果一個過程A呼叫了另外一個過程B,而現在如果過程A中利用SET選項更改了某些引數,那麼這個更改會否影響到過程B的執行環境將呢?答案是不確定。這主要是看過程B中有沒有對這個SET選型進行重新設定。也就是說,除非在過程B中進行了顯示的重置,否則來自所有更高階別的程式碼中的SET選項值在低階別的程式碼中有效。簡單的說,過程A呼叫了過程B,則過程A中的SET選項值在過程B中同樣有效。除非過程B顯示的對這SET選型進行了重置。其實這個原理很簡單,就好象在過程A中定義了一個變數,然後呼叫了過程B。此時過程B使用需要用到這個過程A中定義的變數時,他的值就是在過程A中修改後的值。當然在過程B中也可以對這個過程A中定義的變數值進行修改,如可以對這個變數的值進行重置。不過當這個過程A結束時,這個變數就會失效了。

  可見,這個SET選項跟程式開發過程中的區域性變數與全域性變數非常的相似。資料庫管理員在使用這些SET選項的時候,需要注意一個基本的原則,即其作用範圍往往只在當前的會話或者過程中有效。為此資料庫管理員在啟用某個SET選項的時候,就需要考慮一個問題,即這個改變只是針對某個特定的會話或者某個特定的作業,還是針對全部使用者?如果是前者的話,則可以通過SET選項來設定。但是如果是後者的話,那麼最好通過伺服器設定來改變。否則的話,要為每個會話或者每個作業設定SET選型那工作量就比較大了。筆者以前學過程式開發,為此來學些這個SET選型的時候比較喜歡利用全域性變數與區域性變數的關係來了解這個功能。全域性變數即在整個執行環境中都有效;而區域性變數則只在某個作用範圍內有效。就是如此簡單而已。掌握了這個SET選項的作用範圍之後,就可以幫助資料庫管理員來確定到底是否該採用SET選項、以及在什麼時候採用這個SET選項,來提高客戶端連線以及使用者執行環境的靈活性。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16436858/viewspace-624346/,如需轉載,請註明出處,否則將追究法律責任。

相關文章