久久福利_99r_国产日韩在线视频_直接看av的网站_中文欧美日韩_久久一

您的位置:首頁技術(shù)文章
文章詳情頁

Microsoft SQL Server 查詢處理器的內(nèi)部機制與結(jié)構(gòu)(1)

瀏覽:109日期:2023-10-26 19:48:49
摘要:本文介紹了在客戶機上處理 Microsoft SQL Server 查詢的方式,各種客戶機與 SQL Server 的交互方式,以及 SQL Server 在處理客戶機程序的請求時需要完成的工作。(打印共 26 頁)簡介Microsoft(R) SQL Server(TM) 內(nèi)部機制和結(jié)構(gòu)是一個非常大的主題,因此本文僅限于程序開發(fā)人員感興趣的問題,集中研究其他源中沒有徹底討論的問題。在討論 SQL Server 的結(jié)構(gòu)時,我們主要觀察客戶機的處理過程,研究不同的客戶機程序與 SQL Server 的交互方式,以及 SQL Server 如何處理客戶機的請求。還有一些討論 SQL Server 其他方面的信息源,特別是 Microsoft Press 出版的 Inside SQL Server 7.0,作者是 Ron Soukup 和 Kalen Delaney,這本書非常詳細地討論了 SQL Server 存儲引擎的內(nèi)部機制和處理方法,不過對查詢處理器的討論不夠深入。本文正填補了這個空白。我們期望本文有助于讀者編寫出更好的應(yīng)用程序。通過本文,讀者會在提高程序性能方面得到新的啟發(fā),產(chǎn)生新的理解。SQL Server 是一種客戶機/服務(wù)器系統(tǒng)多年來,SQL Server 一直被認為是一種客戶機/服務(wù)器系統(tǒng)。事實上,Sybase DataServer(以此為基礎(chǔ)開發(fā)了原始的 SQL Server)正是第一個作為客戶機/服務(wù)器系統(tǒng)開發(fā)的商用關(guān)系數(shù)據(jù)庫系統(tǒng)。那這又說明了什么呢?這不只意味著 SQL Server 是一個雙層系統(tǒng)。從傳統(tǒng)上看,雙層系統(tǒng)意味著客戶機應(yīng)用程序運行在一臺機器上,向另一臺計算機上的服務(wù)器發(fā)送請求。而對于 SQL Server,客戶機/服務(wù)器意味著 SQL Server 的組成部分,即客戶機 API 部分,駐留在處理結(jié)構(gòu)中的遠端,與服務(wù)器組件本身是分開的。在典型的雙層模型中,客戶機程序部分駐留在臺式機上,具有大量客戶機應(yīng)用程序邏輯和業(yè)務(wù)邏輯,并且會直接向數(shù)據(jù)庫系統(tǒng)發(fā)出請求。然后,客戶機得到服務(wù)器響應(yīng)這些請求所返回的數(shù)據(jù)。三層系統(tǒng)也采用了同樣的模型。多年以來,SQL Server 一直用在事務(wù)處理監(jiān)視系統(tǒng)中,例如 BEA 的 Tuxedo 以及 Compaq 的 ACMSxp,這些系統(tǒng)早在二、三十年前就采用了典型的三層模型。三層模型在今天基于 Web 的應(yīng)用系統(tǒng)中占據(jù)了支配地位,這類系統(tǒng)以 Microsoft 的 MTS 以及新的 COM+ 1.0 為代表。從 SQL Server 的角度看,三層解決方案中的客戶機程序是放在中間層的。中間層直接與數(shù)據(jù)庫交互。實際的桌面,或瘦客戶機(Thin Client),使用其他機制并通常直接與中間層交互,而不是直接與數(shù)據(jù)庫系統(tǒng)交互。圖 1 描述了這種結(jié)構(gòu)。圖 1. 三層系統(tǒng)模型客戶機結(jié)構(gòu)從結(jié)構(gòu)的角度看,SQL Server 關(guān)系服務(wù)器組件本身并不真正關(guān)心客戶機程序運行的位置。事實上,就 SQL Server 而言,即使在運行 SQL Server 的同一臺機器上運行應(yīng)用程序,仍然還是客戶機/服務(wù)器模型。服務(wù)器運行一個單獨的多線程進程,為來自客戶機的請求提供服務(wù),不管客戶機的位置在哪里。客戶機程序代碼本身是單獨的運行在客戶機應(yīng)用程序內(nèi)部的 DLL,與 SQL Server 的實際接口是在客戶機和服務(wù)器之間對話的“表格數(shù)據(jù)流”(Tabular Data Stream, TDS) 協(xié)議。一個常見的問題是“什么是 SQL Server 的本機接口呢?”很長時間以來,很多開發(fā)人員一直都不愿意使用 ODBC 這樣的接口,因為他們認為由 Sybase 開發(fā)的客戶機 API,也就是 DB-Library,是 SQL Server 的本機接口。實際上,SQL Server 關(guān)系服務(wù)器本身并沒有本機 API,它的接口就是在客戶機和服務(wù)器之間的通信流協(xié)議 TDS。TDS 把客戶機發(fā)送給服務(wù)器的 SQL 語句封裝起來,也把服務(wù)器返回給客戶機的處理結(jié)果封裝起來。任何直接處理 TDS 的 API 都是 SQL Server 的本機接口。讓我們來看一下客戶機的組件,如圖 2 所示。客戶機結(jié)構(gòu)中的某些部分就不在這里討論了,因為它們不屬于 SQL Server 的范疇。但如果您在編寫應(yīng)用程序的話,就必須了解這些部分。大家知道得最多的應(yīng)該是各種對象模型,如果您正在編寫 ASP 或 Microsoft Visual Basic(R) 應(yīng)用程序,就需要通過 ADO 與數(shù)據(jù)庫系統(tǒng)交互,而不是直接調(diào)用底層的 API,例如 ODBC 或 OLE-DB。ADO 映射到 OLE-DB,而 RDO 映射到 ODBC。因此,作為這種最常用的編程模型的對象模型,并不是 SQL Server 客戶機結(jié)構(gòu)中的嚴格意義上的組件。此外,還有另外一些組件可以插接到 SQL Server 基礎(chǔ)結(jié)構(gòu)上面的這一層。OLE-DB 的“會話池服務(wù)提供程序 (Session Pooling Service Provider)”就是這種組件的一個例子。圖 2. 客戶機結(jié)構(gòu)客戶機接口SQL Server 有兩個接口可以認為是 SQL Server 7.0 的本機接口,即 OLE-DB 和 ODBC。DB-Library 接口也是本機的,它與 TDS 通信,但是 DB-Library 使用的是 TDS 較老的版本,需要在服務(wù)器上進行一些轉(zhuǎn)換。現(xiàn)有的 DB-Library 應(yīng)用程序仍然可以繼續(xù)與 SQL Server 7.0 協(xié)同使用,但是很多新的功能和性能提高等好處只能通過 ODBC 和 OLE DB 才能利用。更新 DB-Library 使其支持 SQL Server 7.0 的新能力,將會導(dǎo)致與現(xiàn)有應(yīng)用程序的很多不兼容性,因此需要修改應(yīng)用程序。ODBC 在五年之前就替代了 DB-Library,是新的 SQL Server 應(yīng)用程序更理想的 API,因此引入不兼容的 DB-Library 新版本并不明智。從圖 2 可以看到,所有這些客戶機 API 都有三個部分。最上面的部分實現(xiàn) API 的細節(jié),例如行集和游標應(yīng)該是什么樣等等。TDS 格式化程序負責處理實際請求,例如 SQL 語句,并將其封裝成 TDS 消息包,發(fā)送給 SQL Server,獲得返回的結(jié)果,然后再把結(jié)果反饋到接口實現(xiàn)。還有一些供所有提供程序使用的公共庫代碼。例如,BCP 設(shè)備就是 ODBC 和 OLE-DB 都可以調(diào)用的庫。DTC 也是這樣。第三個例子是 ODBC 規(guī)范的 SQL 語法,即帶有參數(shù)標記的 CALL 語法,這些對于所有提供程序都是通用的。除了我們在前面已經(jīng)提到的局限性,即 DB-Library 仍然只能使用 SQL Server 6.5 版,TDS 協(xié)議對于所有 API 都是相同的。ODBC 和 OLE-DB 在與 SQL Server 7.0 通信時使用 SQL Server 7.0 版,但也能夠與 6.5 或 6.0 服務(wù)器通信。另一個是 Net-Library,這是一個抽象層,客戶機和服務(wù)器都在此層上同網(wǎng)絡(luò)抽象接口通信,不必為 IPX 還是 TCP/IP 困擾。在這里我們將不討論 Net-Library 的工作細節(jié);只要知道它們的工作基本上是將來自的網(wǎng)絡(luò)通信底層的細節(jié)隱藏起來不讓軟件的其他部分看到就可以了。從客戶機的角度看服務(wù)器前面已經(jīng)提到過,客戶機與 SQL Server 通信的主要方法就是通過使用 TDS 消息。TDS 是一種簡單協(xié)議。當 SQL Server 接收到一條消息時,可以認為是發(fā)生了一個事件。首先,客戶機在一個連接上發(fā)送登錄消息(或事件),并得到返回的成功或失敗的響應(yīng)。當您希望發(fā)送 SQL 語句時,客戶機可以把 SQL 語言消息打包發(fā)送給 SQL Server。另外,當您希望調(diào)用存儲過程、系統(tǒng)過程或虛擬系統(tǒng)存儲過程(我們后面還要詳細討論)時,客戶機可以發(fā)送 RPC 消息,這種消息相當于 SQL Server 上的一個 RPC 事件。對于上面的后兩種情況,服務(wù)器會以數(shù)據(jù)令牌流的形式送回結(jié)果。Microsoft 沒有把實際的 TDS 消息寫入文檔中,因為這被認為是 SQL Server 組件之間的私用契約。目錄存儲過程是另一類關(guān)鍵的客戶機/服務(wù)器的交互部分。這些存儲過程首先在 ODBC 的 SQL Server 6.0 中出現(xiàn), 包括諸如 sp_tables 和 sp_columns 等存儲過程。ODBC 和 OLE-DB API 定義了描述有關(guān)數(shù)據(jù)庫對象的元數(shù)據(jù)的標準方法,這些標準需要適用于所有類型的 RDBMS 服務(wù)器,而不必調(diào)整為 SQL Server 自己的系統(tǒng)表。不是客戶機向服務(wù)器發(fā)送對系統(tǒng)表的多個查詢,并在客戶機端建立標準的元數(shù)據(jù)視圖,而是創(chuàng)建一組存儲在服務(wù)器上的系統(tǒng)存儲過程,并對 API 返回適當格式的信息。這種方法使得通過一次通信就可以完成很多重要的元數(shù)據(jù)請求。為 ODBC 編寫的過程已經(jīng)寫入文檔,通常適合需要從系統(tǒng)表中獲取信息但其他機制沒有提供這種方法的情況。這使得 Transact-SQL 過程和 DB-Library 應(yīng)用程序可以訪問元數(shù)據(jù),而不需要編寫對 SQL Server 系統(tǒng)表的復(fù)雜查詢,并且使應(yīng)用程序不受今后 Microsoft 修改系統(tǒng)表的影響。OLE DB 定義了一組架構(gòu)行集,它們類似于 ODBC 的元數(shù)據(jù),但又和它不同。它創(chuàng)建了一組新的目錄存儲過程,以更有效地為這些架構(gòu)行集植入數(shù)據(jù)。但是,這組新的存儲過程沒有寫入文檔,因為這些存儲過程重復(fù)了早先提供的功能。通過現(xiàn)有的若干種方法都可以得到元數(shù)據(jù),因此 SQL Server 開發(fā)組決定不顯露這些并沒有為編程模型增加新內(nèi)容的對象。 客戶機與服務(wù)器的交互還有第三個方面。它最初出現(xiàn)在 SQL Server 6.0 中,但是沒有得到普遍使用。這就是虛擬系統(tǒng)存儲過程的概念;在 SQL Server 7.0 中起很重要的作用。當?shù)谝淮螢?SQL Server 6.0 開發(fā)服務(wù)器端游標時,開發(fā)人員就需要選擇采取什么方法管理客戶機/服務(wù)器的交互。游標并不特別適合現(xiàn)有的 TDS 消息,因為這些消息允許逐行返回數(shù)據(jù),不需要客戶機指定額外的 SQL 語句。開發(fā)人員本來可以向 TDS 協(xié)議添加更多的消息,但是需要修改太多的其他組件。SQL Server 6.0 中的 TDS 版本還需要向 Sybase 版本靠攏,以便確保兩者的可互操作性,于是開發(fā)人員選擇了另外的處理機制。他們開發(fā)了外表看起來像是系統(tǒng)存儲過程的新功能(服務(wù)器端游標),實際上是指向 SQL Server 代碼的入口存儲過程。它們被客戶機應(yīng)用程序使用標準的 RPC TDS 消息來調(diào)用。它們被稱為虛擬系統(tǒng)存儲過程,因為在客戶機上,它們像其他存儲過程那樣被調(diào)用,和其他存儲過程不同的是,它們并不是由簡單的 SQL 語句組成。大多數(shù)虛擬系統(tǒng)存儲過程都是私用的,并且沒有寫入文檔。對于游標過程,所有 API 都顯露其自有的一組游標 API 模型和它們自己的游標操作函數(shù),因此沒有必要為存儲過程本身編寫文檔。即使是在 Transact-SQL 語言中,也有顯露游標的語法,可以使用 DECLARE、OPEN、FETCH 等,所以完全沒有必要為虛擬系統(tǒng)存儲過程編寫文檔,例如 sp_cursor,因為這些過程只在內(nèi)部使用。ODBC 和 OLE DB 中出現(xiàn)了帶參數(shù)的查詢和準備/執(zhí)行模型的概念。在 SQL Server 7.0 以前的版本中,這些概念是由客戶機 API 中的代碼實現(xiàn)的。在 SQL Server 7.0 中,Microsoft 為這些概念添加了對“關(guān)系服務(wù)器”的支持,并且通過新的虛擬系統(tǒng)存儲過程顯露了這種支持。本文后面還要介紹這些功能,以及服務(wù)器如何支持這些功能。通過 sp_executesql 過程對帶參數(shù)的查詢的支持,被認為對直接 Transact-SQL 和 DB-Library 的使用特別有用,所以將其寫入了文檔。準備/ 執(zhí)行的過程,被 ODBC 驅(qū)動程序和 OLE DB 提供程序?qū)S谩_@樣,可以與 SQL Server 通信的所有客戶機程序,都建立在這三組功能之上:TDS 協(xié)議、目錄存儲過程和虛擬系統(tǒng)存儲過程。服務(wù)器結(jié)構(gòu)SQL Server,或更確切一點地說,是“SQL Server 關(guān)系服務(wù)器”,經(jīng)常被說成是由兩個主要部分組成,即關(guān)系引擎和存儲引擎。正如前面提到過的那樣,已經(jīng)有很多文獻介紹存儲引擎的細節(jié)了,所以本文主要介紹關(guān)系引擎的功能。圖 3 給出了 SQL Server 關(guān)系引擎部分的主要組件。所給出的組件可以分為三組子系統(tǒng)。左邊的組件編譯查詢,包括查詢優(yōu)化器。查詢優(yōu)化器是所有關(guān)系數(shù)據(jù)庫引擎中的最神秘的部分之一,從性能的角度看也是最重要的部分。查詢優(yōu)化器負責提取 SQL 語句中的非過程請求部分,并將其翻譯成一組磁盤 I/O、過濾以及其他能夠高效地滿足該請求的過程邏輯。圖中右側(cè)是執(zhí)行基礎(chǔ)結(jié)構(gòu)。這里實際上只有很少的功能。當編譯組件的工作完成之后,所產(chǎn)生的結(jié)果只需用很少幾個服務(wù)即可直接執(zhí)行。圖 3. 服務(wù)器結(jié)構(gòu)圖的中間是稱為 SQL Manager 的部分。SQL Manager 控制著 SQL Server 內(nèi)部的所有數(shù)據(jù)的流動。SQL Manager 控制著 RPC 消息,在 SQL Server 7.0 中,絕大多數(shù)來自客戶機的功能調(diào)用都是通過 RPC 消息進行的。上一節(jié)中介紹的虛擬系統(tǒng)存儲過程邏輯上也是 SQL Manager 的一部分。通常,作為 TDS SQL 語言消息的 SQL 語句直接在編譯一端執(zhí)行,與早期版本相比,SQL Server 7.0 較少使用這種方法,但還算是比較常見的。執(zhí)行結(jié)果由稱為 ODS 的執(zhí)行引擎中的組件格式化為 TDS 執(zhí)行結(jié)果消息。絕大多數(shù)輸出都來自圖中的執(zhí)行端,而且輸出結(jié)果也真正出自表達式服務(wù)。“表達式服務(wù)”庫是進行數(shù)據(jù)轉(zhuǎn)換、謂詞評估(過濾)以及算法計算的組件。它還利用了 ODS 層,把輸出結(jié)果格式化為 TDS 消息。還有幾個組件,我們只是在這里簡單地提一下,這些組件在關(guān)系引擎內(nèi)部提供附加服務(wù)。這些組件中的一個是目錄服務(wù)組件,用于數(shù)據(jù)定義語句,例如 CREATE TABLE、CREATE VIEW 等。目錄服務(wù)組件主要放在關(guān)系引擎中,但是實際上大約有三分之一的目錄服務(wù)組件是在存儲引擎中運行的,所以可以看作是共享組件。關(guān)系引擎中的另一種組件是“用戶模式調(diào)度程序 (UMS)”,這是 SQL Server 自己內(nèi)部的纖程和線程規(guī)劃器。把任務(wù)分配給纖程或線程是一種非常復(fù)雜的內(nèi)部機制,取決于對服務(wù)器如何配置,以及在 SMP 系統(tǒng)中允許 SQL Server 進行處理器之間的適當?shù)呢撦d平衡。UMS 還可以避免 SQL Server 由于同時運行太多的線程而導(dǎo)致性能過低。最后,還有大家熟悉的系統(tǒng)過程,邏輯上它們也屬于關(guān)系引擎的一部分。這些組件肯定不是服務(wù)器代碼,因為可以很容易地使用 sp_helptext 檢查定義這些過程的 Transact-SQL 代碼。但是,系統(tǒng)過程被作為服務(wù)器的一部分來對待,因為系統(tǒng)過程的用途是顯露重要的服務(wù)器能力,像系統(tǒng)表一樣,以供應(yīng)用程序在更高的層次上和更適當?shù)膶哟紊鲜褂谩H绻麘?yīng)用程序開發(fā)人員將較高層次的系統(tǒng)過程 — 更容易使用 — 作為一種接口,即使隨著版本的更新,原始層次上的系統(tǒng)表發(fā)生變化時,應(yīng)用程序仍然可以繼續(xù)使用。處理 SQL 語句時的客戶機/服務(wù)器交互下面我們將討論當客戶機應(yīng)用程序與 SQL Server 交互時客戶機的動作。以下是一個 ODBC 調(diào)用的例子:SQLExecDirect(hstmt, "SELECT * FROM parts where partid = 7", SQL_NTS)(OLE-DB 也有一個與這個調(diào)用幾乎直接等價的調(diào)用,此處不再討論這個調(diào)用,因為這個調(diào)用實際上與 ODBC 調(diào)用相同。)該 ODBC 調(diào)用取一個 SQL 語句,然后將其發(fā)送給 SQL Server 來執(zhí)行。在這個具體的查詢語句中,我們從零件表中提取具有特定零件標識號的所有行。這是特定 SQL 的一個典型例子。在 SQL Server 7.0 以前的版本中,特定的 SQL 與存儲過程的一個顯著差別是,查詢優(yōu)化器所生成的計劃從不緩存。查詢語句要被讀入、編譯、執(zhí)行,然后再拋棄計劃。在 SQL Server 7.0 中,正如稍后還要討論的,實際上提供了可以緩存特定查詢語句的計劃的機制。在這條語句被送往 SQL Server 之前,還必須要問幾個問題。所有客戶機程序都要提供某種游標說明,所以客戶機程序在內(nèi)部必須詢問的一個問題是,程序員請求的是什么樣的結(jié)果集或什么樣的游標。最快的類型是在文檔中被稱為默認結(jié)果集的游標。這種游標由于歷史上的原因被稱為消防站游標,有時甚至根本不把它作為游標看待。當 SQL 請求被送到服務(wù)器之后,服務(wù)器開始把結(jié)果返回給客戶機,這個返回結(jié)果的過程持續(xù)進行,直到把全部數(shù)據(jù)集發(fā)送完畢為止。這就像一個將數(shù)據(jù)抽給客戶機的大型消防站。一旦客戶機程序確定了這是默認結(jié)果集,則下一步就是確定是否有參數(shù)標記。使用這個 ODBC SQLExecDirect(以及 OLE-DB 中等價的調(diào)用)調(diào)用的選項之一是,不是在 WHERE 從句中給出像 7 這樣的具體值,而是可以用一個問號來傳遞參數(shù)標記,如下所示:SQLExecDirect(hstmt, "SELECT * FROM parts where partid = ?", SQL_NTS)請注意,您必須分別提供實際的參數(shù)值。客戶機需要知道 SQL 語句中是否有參數(shù)標記,或者它是否為真正特定的非參數(shù)化 SQL。這將影響到客戶機將用這個語句在內(nèi)部做什么,并確定將什么作為消息真正發(fā)送給 SQL Server。在沒有問號時,很明顯,客戶機只想將這個請求作為 SQL Language TDS 消息發(fā)送,然后客戶機將位于流水的末端,并將結(jié)果返回。然后客戶機能將結(jié)果返回給基于應(yīng)用程序參數(shù)的應(yīng)用程序。客戶機的內(nèi)部處理選擇會模糊一點,這取決于您通過 ODBC 或 OLE DB API 請求什么。例如,應(yīng)用程序不直接請求默認結(jié)果集。相反,在 ODBC 中,如果請求一個只讀的、只向前的且每次只給出一行的游標,那么對于客戶機內(nèi)部運行來說,這就是在定義流水游標(默認結(jié)果集)。流水游標有一個主要問題。除非客戶機已將所有的行全部接收完畢,客戶機不能將任何其他 SQL 語句向下發(fā)送給服務(wù)器。因為結(jié)果集可能有很多行,所以有些應(yīng)用程序使用流水游標時不能順利運行。后面將要描述的只向前的快速游標,是 SQL Server 7.0 版的一個新特點,尤其適合于處理這種情況。在 SQL Server 7.0 版之前,SQLExecDirect 調(diào)用在很大程度上是以相同方式處理的,而不管是否用參數(shù)標記來代替常數(shù)。如果您定義一個參數(shù)標記,客戶機將實際取您通過不同調(diào)用提供的值(本節(jié)的開始示例中的值“7”),并將它插入問號處。然后,使用代替值的新語句被向下發(fā)送,作為一個特定的 SQL 語句。在服務(wù)器上使用參數(shù)化的 SQL 沒有任何好處。然而,在 SQL Server 7.0 版中,如果 SQLExecDirect 使用了參數(shù)標記,向下發(fā)送給 SQL Server 的 TDS 消息便不是 SQL 語言消息。相反,它被下發(fā)給使用 sp_executesql 過程的服務(wù)器,所以,就 TDS 協(xié)議來說,它是 RPC。在客戶機上,結(jié)果基本上相同。客戶機將取回數(shù)據(jù)流水。如果您不想取回這個數(shù)據(jù)流水,則可以始終使用塊游標或可滾動游標。在這種情況下,數(shù)據(jù)流變得大不相同。調(diào)用是對通過 SQL 文本中的 sp_cursoropen 輸入點(這些虛擬存儲過程之一)進行的。該 sp_cursoropen 利用 SQL 來增加附加邏輯,以使其滾動,它潛在地將某些結(jié)果重定向到一個臨時表,然后用句柄給游標一個響應(yīng),表明游標現(xiàn)在是打開的。仍然在程序員的控制之外,客戶機調(diào)用 sp_cursorfetch,將一行或多行轉(zhuǎn)到客戶機上,然后返回到用戶應(yīng)用程序。客戶機還可使用 sp_cursor 來重新配置游標,或改變某些統(tǒng)計數(shù)字。在您處理完游標之后,客戶機將調(diào)用 sp_cursorclose。讓我們看一個簡單的情況,即只返回一行給客戶機。至于默認的結(jié)果集,需要從客戶機到服務(wù)器往返發(fā)送一次消息。 SQL 消息(或 sp_executesql)向下發(fā)往服務(wù)器,然后結(jié)果返回來。在同一行(非流水)的游標情況下,您會看到傳統(tǒng)情況下能用 SQL Server 看見的東西。一個往返行程用于打開,一個往返行程用于取得數(shù)據(jù),一個往返行程用于關(guān)閉。這個過程使用消息的次數(shù)是默認結(jié)果集使用的三倍。在 SQL Server 7.0 中,有一種所謂只向前的快速游標, 它使用同樣的游標結(jié)構(gòu)。它與流水的表現(xiàn)不一樣,因為在發(fā)送任何附加 SQL 消息之前,它不需要您處理全部結(jié)果行。所以,如果您帶回 5 行,還有更多的數(shù)據(jù),您仍能將更新向下發(fā)送給服務(wù)器。一個只向前的快速游標在服務(wù)器上比常規(guī)游標更快,它讓您指定兩個附加選項。一個稱為自動取數(shù),另一個稱為自動關(guān)閉。自動取數(shù)將返回第一個行集合,作為打開的響應(yīng)消息的一部分。自動關(guān)閉在讀完最后一行后自動關(guān)閉游標。因為它是只向前的和只讀的,所以不能回滾。SQL Server 只傳回一個帶有說明游標已關(guān)閉的最后數(shù)據(jù)集的消息。如果您正在使用只向前的快速游標,則在行數(shù)少的消息里,您可向下與同一往返行程通信。如果您有很多行,則您至少還要對每一行塊支付附加開銷。如果您使用只向前的快速游標,那么游標處理會更加接近默認的結(jié)果集。SQLExecDirect 模型流程如圖 4 所示。圖 4. 客戶機/服務(wù)器交互準備/執(zhí)行模型除了執(zhí)行直接模型(在 ODBC 中用 SQLExecDirect 調(diào)用)外,在 ODBC 和 OLE-DB 中,還有一種執(zhí)行模型,稱為準備/ 執(zhí)行模型。定義要執(zhí)行的 SQL,是作為一個獨立于實際執(zhí)行 SQL 的步驟來完成的。以下是 ODBC 中的一個例子:SQLPrepare(hstmt, "SELECT * FROM parts where partid = ?", SQL_NTS)SQLExecute(hstmt)在 SQL Server 7.0 版本之前,準備/執(zhí)行從來都不是 SQL Server 的本機模式。如今在 7.0 版本中,有兩個提供本機接口的虛擬系統(tǒng)存儲過程。對于準備調(diào)用,我們要再次研究游標的類型,然后調(diào)用 sp_prepare 或 sp_cursorprepare。這些過程會完成 SQL 或存儲過程的編譯,但不會實際執(zhí)行計劃。相反,虛擬系統(tǒng)存儲過程只是返回該計劃的句柄。現(xiàn)在,應(yīng)用程序可以反復(fù)地執(zhí)行 SQL 了,例如傳入不同的參數(shù)值,而不需要重新編譯。在 SQL Server 6.5 中,由于沒有本機接口,需要模擬準備和執(zhí)行兩個階段。可以通過下面的兩種方法做到這一點。在第一種方法中,不會真正出現(xiàn)準備階段。只有執(zhí)行部分返回元數(shù)據(jù)(有一些選項可以做到這一點),所以 SQL Server 可以把結(jié)果的格式描述返回給應(yīng)用程序。在第二種方法中,SQL Server 實際上創(chuàng)建一個特定存儲過程,這個過程是單個用戶私用的,不能共享計劃。這第二種方法可能會占滿 tempdb 數(shù)據(jù)庫的空間,因此大多數(shù)應(yīng)用程序開發(fā)人員都通過 ODBC 配置對話框中的復(fù)選框,關(guān)閉此選項,以使用第二種方法。在 SQL Server 7.0 中,準備/執(zhí)行方法是 SQL Server 的本機功能。準備好 SQL 語句之后,才會執(zhí)行它。至于默認的結(jié)果集,應(yīng)用程序只需要調(diào)用 sp_execute,提供準備操作生成的句柄,語句就會被執(zhí)行。對于游標,與其他游標處理過程看起來很相似,事實上,它也具有相同的特性,包括如果游標是快速只前向型,還可以使用 autofetch 和 toclose。準備/執(zhí)行操作的流程如圖 5 所示。
主站蜘蛛池模板: 亚洲美女av在线 | 日本成年人免费网站 | 中国电影黄色一级片免费观看 | 九色av | 蜜桃官网| 亚洲精品一区国产精品 | 高清国产一区二区三区四区五区 | 国产激情在线看 | 男人的天堂亚洲 | 久久精品亚洲欧美日韩精品中文字幕 | 91在线综合 | 国产高清一区二区三区 | 色黄视频在线 | 国产一二区在线 | 蜜桃视频一区二区三区 | 99精品久久久久久久免费看蜜月 | 午夜一区二区三区在线观看 | 国产精品亚洲成在人线 | 久久国产精品久久久久久电车 | 色视频网站在线观看 | 国产黄色大片免费看 | 久久精品超碰 | 精品久久久久久国产 | 国产精品久久久久一区二区三区共 | 亚洲精品久久久久久一区二区 | 中文字幕一区二区在线观看 | 9999久久久久 | 久久精品国产亚洲blacked | www国产亚洲精品久久网站 | 久久精品99 | 黄色毛片一级 | 欧美bbbxxx | 久久国产午夜 | 黄色一级毛片免费 | 黄网站在线播放 | 亚洲国产一区二区三区四区 | 国产日韩欧美一区 | 国产区精品在线 | 中文字幕1区| 国产精品永久 | 91精品国产综合久久久久久丝袜 |