文章編號: 190987 - 上次校閱: 2006年5月9日 - 版次: 6.4

如何使用延伸預存程序

系統提示本文適用於您使用的作業系統之外的作業系統。與您不相關的文章內容已停用。

在此頁中

全部展開 | 全部摺疊

結論

本文將告訴您,適當的建立和延伸預存程序的 SQL Server 的實作。此外,這篇文章提供詳細資料,並參考執行成功的實作,SQL Server 的延伸預存程序。

延伸預存程序是一個非常強大的方法來擴充功能的 SQL Server。下列摘錄是從 [SQL Server 線上叢書 》:
延伸預存程序類似不著痕跡地延伸 SQL Server 是預存程序的方式提供的方法來動態地載入及執行動態連結程式庫 (DLL) 內的函式的功能。外的 SQL Server 的動作都可以輕易地觸發和外部資訊傳回給 SQL Server。也支援傳回狀態碼和輸出參數 (等於其規則的預存程序中的複本分離出來)。SQL Server 包含系統預存程序,加入 (sp_addextendedproc)、 卸除 (sp_dropextendedproc) 和提供資訊 (sp_helpextededproc) 延伸預存程序。
您必須將延伸預存程序 DLL 視為其他 DLL 開發: 是共用的程式碼,而且多個執行緒可以存取在同一時間。如同任何 production-worthy 專案請確定您使用完整的設計,並完成測試。

若要撰寫成功的延伸預存程序,您需要的許多主題的工作知識。若要檢閱這些主題,請參閱 進階 Windows Jeffrey Richter 由下列的章節:
  • 章節 3 」 的處理序 」
  • 本章 4 執行緒"
  • 章節 10"執行緒同步處理"
  • 章節 12 」 動態連結程式庫"
  • 章節 13"執行緒區域儲存區"
  • 第 16 章、 結構化例外處理
更多有關如何撰寫安全的程式碼,當您使用延伸預存程序的資訊,請參閱由 Michael Howard 和 David LeBlanc 撰寫安全程式碼。如需有關這本書的詳細資訊,請造訪下列 Microsoft 網站]:
http://www.microsoft.com/products/info/product.aspx?view=22&pcid=ab0cdef1-acfe-71c1-d09b-06567808e1e7 (http://www.microsoft.com/products/info/product.aspx?view=22&pcid=ab0cdef1-acfe-71c1-d09b-06567808e1e7)

註冊

延伸預存程序架構不複雜 ; 它是 Microsoft Visual C + + 連結與公開正確匯出函式 (或函數) Opends60.lib 檔案的相容 DLL。您可以使用 sp_addextendedproc 預存程序來登錄匯出的函式名稱和相關聯的 DLL。請參閱 xpxp_dblibxp_odbc 範例的 SQL Server 開發者工具組中的範例。如果要存取 SQL Server 開發者工具組,請造訪 SQL Server 頁面在下列 Microsoft 網站:
http://www.microsoft.com/sql/default.mspx (http://www.microsoft.com/sql/default.mspx)
延伸預存程序都登錄在 master 資料庫及系統管理員 (SA) 維護控制其使用方式和註冊。

當您註冊您的 DLL 時,請確定它是目前的系統路徑中,並且它跟 8.3 檔案命名慣例。

如需詳細資訊,請按一下下列的文件編號,檢視 「 Microsoft 知識庫 」 中的文件:
151596? (http://support.microsoft.com/kb/151596/ ) 擴充程序錯誤: 「 找不到 DLL 'xxx.dll'"

位址空間

SQL Server 使用 LoadLibrary、 GetModuleHandle 和 GetProcAddress 來取得匯出函式的指標,並接著它會傳遞函式 SRVPROC 結構。DLL 會接收 SRVPROC 結構之後您就可以執行標準的開放式資料服務作業取得參數,並傳回給呼叫者的結果。

為一個 DLL,就會載入呼叫的處理程序位址空間中。在延伸預存程序的情況下,過程都是 SQL Server。如果 DLL 不當記憶體或如果它不是安全執行緒存取,您可以有不利影響處理序。您必須執行徹底的測試,以確定該 DLL 會維護處理程序的完整性。如果您在所有擔心延伸預存程序可能會造成不利影響 SQL Server 必須立即解決這個問題。

比方說您可以使用 Microsoft Visual C 或 Microsoft Visual C++ 精靈來建立 DevStudio 增益集精靈 」。此精靈是一個內含式 COM] 伺服器或 DLL。如果您不要正確寫入您的精靈,它可能會造成不良的影響處理序。

範例

   char strName[31] = "";
   strncpy(strName, "Bob", 35); //  <-- Incorrect length
				
在這個範例您在不正確地複製資料超過 strName 緩衝區結尾。strncpy 常式的文件中聲明它會將第二個字串複製到 strName] 參數,然後再零填滿其餘的緩衝區。因此,範例正在寫入 35 個位元組,即使當第二個字串是 3 個位元組的長度。因為您仍在處理序位址空間 strncpy 常式最有可能不會造成存取違規。不過,作業可能會有很容易地毀損可能造成未預期的處理序行為的一個內部記憶體] 結構。在 SQL Server 處理程序的情況下這種類型的錯誤可能會損毀重要的內部 SQL Server 結構,,像這類可能會顯示本身透過已卸除的連線或其他未預期的 SQL Server 行為。此外,伺服器可能會停止回應。

SQL Server 會試著保護位址空間。延伸預存程序的引動過程包裝中一試 / 除了區塊,並在程式碼中的多點執行最少的 Runtime 正確性檢查。請務必記住保護係由一試 / 除了區塊而不是 try/catch 區塊。因此,程式碼將不會執行堆疊回溯的物件。

記憶體遺漏 (Memory Leak)

任何專案可能有問題位置配置的記憶體、 在控點或類似的資源不被釋放正確。它是最重要套件可確保 DLL 已正確地釋放所有資源的任何 DLL 測試套件。這類問題很可能會自己顯示為增加的分頁檔使用量、 更改過的效能或增加的分頁。

執行緒安全

應用程式 (例如 Microsoft 網際網路資訊伺服器 (IIS) 及 Microsoft SQL Server 是執行緒共用多執行緒應用程式。這表示您可以啟動您的 DLL 從多個連線在同一時間有多個處理器的電腦上的特別。這也表示單一連線可以不同的進入點的 DLL (XPROC,ISAPI) 叫用從不同的背景工作執行緒。執行緒集區可以限制執行緒本機存放區 (TLS) 變數的可用性。

請確定所有的程式碼路徑是安全執行緒和 re-entrant 藉由連結多執行緒的執行階段程式庫,以及確定所有廠商您都正在使用的 DLL 都執行緒安全。

如需有關執行緒區域儲存區和執行緒安全問題的詳細的帳戶,按一下下面的文件編號,檢視 「 Microsoft 知識庫 」 中的發行項:
163449? (http://support.microsoft.com/kb/163449/ ) 在延伸預存程序中執行緒區域儲存區的使用

結構的例外處理

您必須也清楚地了解結構化的例外狀況錯誤處理。在 DLL 中的每個進入點必須正確負責例外狀況錯誤。SQL Server 會嘗試攔截例外狀況錯誤,但任何 DLL 來擷取並適當地處理例外狀況錯誤。特別,在 DLL 中啟動任何執行緒必須安裝結構化的例外狀況錯誤處理常式。

每個執行緒在處理程序中的有例外狀況堆疊。不過,如果 DLL 會啟動新執行緒,它啟動其例外狀況 Naked。如果執行緒並不安裝一試 / 除非或 try/catch 區塊立即,執行緒只受作業系統。執行緒遇到的任何例外狀況錯誤會被視為 unhanded 和嚴重整個程序。請記住,[DLL 是呼叫端處理序空間中,這種類型的問題會導致嚴重的例外狀況,到處理程序。

SQL Server 和相關聯的元件,SQL Server 的連結與執行階段 DLL 版本中。您開發任何延伸預存程序也必須連結與執行階段 DLL 版本。

回送連線

延伸預存程序進行連線回到同一個執行 SQL Server 的電腦時,是建立回送連線。這些描述 xp_dblibxp_odbc 範例,也就是隨附於 SQL Server 開發者工具組中。

您只可以在繫結的工作階段上執行回送連線。回送連線的一個問題是它是新的連線,因此位於個別交易空間。比方說假設延伸預存程序 sales 資料表上執行複雜的數學計算。回送連線嘗試完成 sales 資料表的 SELECT 陳述式。但是,原始連線必須執行 UPDATE 陳述式到 銷售 資料表。除非您已採取用心注意若要實作查詢逾時,以執行非同步查詢處理,並檢查 SRV_GOTATTENTION,這個連線可能會封鎖本身。
SQL Server 6.5 和稍後組建的 SQL Server 支援繫結的連線。 請參閱 srv_getbindtokensp_bindsession 用於實作細節。繫結至原始連線的回送連線會將這兩個連線放在同一個交易空間中。這表示,原先 銷售 資料表中發生在區塊可以避免這種情況發生。

附註SQL Server 只支援繫結的工作階段上的回送連線。

如更多有關封鎖問題的資訊,按一下下面的文件編號,檢視 「 Microsoft 知識庫 」 中 「 文件:
162361? (http://support.microsoft.com/kb/162361/ ) 瞭解並解決 SQL Server 6.x 封鎖問題
180775? (http://support.microsoft.com/kb/180775/ ) 在 SQL Server 產能上的用戶端效果

錯誤和訊息

回送連線或會連接至另一個執行 SQL Server 的電腦或開放式資料服務閘道的延伸預存程序的另一個的一環是處理錯誤與訊息。

如果您使用資料程式庫,您必須使用每個處理程序錯誤和訊息處理常式。SQL Server 控制通用訊息處理常式,並延伸預存程序必須不取代它們。每個處理程序錯誤和訊息處理常式也保證是安全執行緒。請參閱 dbprocmsghandledbprocerrhandle 完整詳細資料。

提示安裝它們在 [LOGINREC 呼叫 dbopen 之前。

如擴充環境中的資料程式庫使用方式限制更多有關,按一下 [下面的文件編號,檢視 「 Microsoft 知識庫 」 中的發行項]:
174817? (http://support.microsoft.com/kb/174817/ ) Microsoft SQL Server 資料程式庫已限制了擴充性
與開啟的資料服務 API 呼叫 srv_message_handler,可將文字放在 SQL Server 錯誤記錄檔中。如需詳細資訊,請按一下下列的文件編號,檢視 「 Microsoft 知識庫 」 中的文件:
164290? (http://support.microsoft.com/kb/164290/ ) FIX: Srv_message_handler 文字限制
關於資料程式庫錯誤處理常式的最後一個注意事項: 您可以從已安裝的回呼函式傳回 INT_EXIT 值。不過,如記載,它就會造成 EXIT 應用程式。這表示您指示最佳化 EXIT 處理程序。因此,它必須不會呼叫從 DLL 因為效果的 IIS 或 SQL Server 這類的應用程式。

Transact-SQL KILL

回送連線或延伸預存程序執行的另一個觀點的一般是殺死 Transact-SQL 陳述式使用。因為 KILL 陳述式 Transact-SQL 根據目前開啟的資料服務 API 集具有不知道 Transact-SQL 殺死狀態。延伸預存程序必須看起來 SRV_GOTATTENTION 所以它可以處理來自用戶端的要求取消作業。不過,SA 目前無法發出殺死 Transact-SQL 陳述式,以中斷延伸預存程序執行。這樣就更重要您正確地使用繫結的連線和好程式碼撰寫實務。將設計變更要求 (DCR) 已被歸檔與 SQL Server 開發來擴充殺死 Transact-SQL 陳述式來延伸預存程序功能。

通用設定

永遠不會影響從 DLL 的程序的全域狀態。比方說 SQL Server 特別呼叫 Win32 API 呼叫 SetErrorMode 來設定想要的行為。延伸預存程序必須永遠不會呼叫 SetErrorMode 或其他處理序全域呼叫,因為這是通用的處理序空間。有數個其他呼叫的全域會影響處理序 ; 請確定該 DLL 並不會使用這些呼叫。

此外,某些開啟資料服務 (ODS) 只針對所設計的呼叫使用 ODS 為基礎的應用程式中,且不必須延伸預存程序中使用。 這些包括呼叫例如 srv_initsrv_configsrv_handlesrv_errhandle。呼叫這些函式會覆寫的值,SQL Server 安裝,並可能導致無法預期的失敗狀況。

Srv_Senddone

預設情況下,SQL Server 會自動呼叫延伸預存程序與 SRV_DONE_FINAL 旗標在延伸預存程序的引動過程的傳回 srv_senddone。延伸預存程序必須 呼叫 srv_senddone SRV_DONE_FINAL 旗標 ; 而是,它必須使用 SRV_DONE_MORE 旗標。

字串終止

當您處理從開啟的資料服務 API 傳回的字串時, 必須請務必便結束。終止從 srv_paramdata 延伸預存程序不保證一定會有空值傳回的字串。您必須使用 srv_paramlen 延伸預存程序正常操作之字串。開放式資料服務的其他函式可能類似; 徹底測試。

?考

Richter 為 Jeffrey。進階的 Windows。1997,雷蒙: Microsoft 按

Howard、 Michael 和 David LeBlanc。撰寫安全程式碼,第二版。2002,雷蒙: Microsoft 按。

這篇文章中的資訊適用於:
  • Microsoft SQL Server 2000 Standard Edition
  • Microsoft SQL Server 2000 64-bit Edition
  • Microsoft SQL Server 7.0 Standard Edition
  • Microsoft SQL Server 6.5 Standard Edition
關鍵字:?
kbmt kbhowtomaster kbprogramming KB190987 KbMtzh
機器翻譯機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:190987? (http://support.microsoft.com/kb/190987/en-us/ )
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。