国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Microsoft SQL Server 2000 分布式查詢:OLE DB 連接
摘要:本文描述了 Microsoft SQL Server 2000 查詢處理器如何與 OLE DB 提供程序進行交互以實現(xiàn)分布式和異類查詢。它面向的讀者主要是 OLE DB 提供程序開發(fā)人員,并假設讀者對 OLE DB 規(guī)范有深入的了解。
目錄
簡介
概述和術語
OLE DB 提供程序交互階段
查詢執(zhí)行方案
總結
附錄 A:SQL Server 采用的 OLE DB 接口
附錄 B: 用于生成遠程查詢的 SQL 子集
簡介
本文描述了 Microsoft® SQL Server™ 2000 查詢處理器如何與 OLE DB 提供程序進行交互以實現(xiàn)分布式和異類查詢。它面向的讀者主要是 OLE DB 提供程序開發(fā)人員,并假設讀者對 OLE DB 規(guī)范有深入的了解。本文重點在于描述 SQL Server 查詢處理器和 OLE DB 提供程序之間的 OLE DB 接口,而不是分布式查詢功能本身。有關分布式查詢功能的完整描述,請參閱 SQL Server Books Online。
概述和術語
在 Microsoft SQL Server 2000 中,分布式查詢允許 SQL Server 用戶訪問基于 SQL Server 的服務器以外的數(shù)據(jù)(位于其他運行 SQL Server 的服務器或是具有 OLE DB 接口的其他數(shù)據(jù)源中)。OLE DB 提供了統(tǒng)一的方式來訪問異類數(shù)據(jù)源中的列表數(shù)據(jù)。
在本文中,分布式查詢是指任何引用了一個或多個外部 OLE DB 數(shù)據(jù)源中表或行集的 SELECT、INSERT、UPDATE 或 DELETE 語句。
遠程表是指存儲于 OLE DB 數(shù)據(jù)源中并且不在執(zhí)行查詢的 SQL Server 所在服務器上的表。一個分布式查詢可以訪問一個或多個遠程表。
OLE DB 提供程序類別
根據(jù) OLE DB 提供程序在 SQL Server 的分布式查詢中的功能,我們將它們劃分為如下類別。根據(jù)定義,它們并非互相排斥;某種提供程序可能屬于一個或多個類別: SQL 命令提供程序
索引提供程序
簡單表提供程序
非 SQL 命令提供程序
SQL 命令提供程序
凡是以 SQL 標準語法(SQL Server 認可)支持 Command 對象的提供程序,都屬于此類別。下面是 OLE DB 提供程序被 SQL Server 視為 SQL 命令提供程序的必要條件: 提供程序必須支持 Command 對象及其所有強制 OLE DB 接口:ICommand、ICommandText、IColumnsInfo、ICommandProperties 和 IAccessor。
提供程序支持的 SQL 語法必須至少是 SQL 子集。提供程序必須通過 DBPROP_SQLSUPPORT 屬性來報告語法。
SQL 命令提供程序的示例為:Microsoft OLE DB Provider for SQL Server 和 Microsoft OLE DB Provider for ODBC。
索引提供程序
索引提供程序支持并提供與 OLE DB 對應的索引,同時還允許基于索引對基本表執(zhí)行查找。下面是 OLE DB 提供程序被 SQL Server 視為索引提供程序的必要條件: 提供程序必須以 TABLES、COLUMNS 和 INDEXES 架構行集支持 IDBSchemaRowset 接口。
提供程序必須支持通過 IOpenRowset 打開索引中的行集(通過指定索引名和相應的基本表名稱)。
Index 對象必須支持其所有的強制接口:IRowset、IRowsetIndex、IAccessor、IColumnsInfo、IRowsetInfo 和 IConvertTypes。
對帶索引基本表打開的行集(通過使用 IOpenRowset)必須支持 IRowsetLocate 接口,以便根據(jù)書簽在行上定位。
如果一個 OLE DB 提供程序滿足以上條件,用戶可以設置提供程序選項 Index As Access Path,以允許 SQL Server 使用提供程序的索引來執(zhí)行查詢。默認情況下,除非該選項已被設置,否則 SQL Server 不會嘗試使用提供程序的索引。
注意:   SQL Server 支持多個影響 SQL Server 訪問 OLE DB 提供程序的方法的選項??梢允褂?SQL Server 企業(yè)管理器中的“鏈接服務器屬性”對話框來設置這些選項。
簡單表提供程序
簡單表提供程序通過 IOpenRowset 接口來表現(xiàn)根據(jù)基本表打開行集的方式。這些提供程序既不是 SQL 命令提供程序也不是索引提供程序;而是 SQL Server 分布式查詢所能處理的提供程序中最簡單的一類。
對于此類提供程序,SQL Server 僅能在分布式查詢運行過程執(zhí)行表掃描操作。
非 SQL 命令提供程序
該類提供程序支持 Command 對象及其所有強制接口,但不支持 SQL Server 認可的 SQL 標準語法。
非 SQL 命令提供程序的兩個示例是:Microsoft OLE DB Provider for Indexing Service 和 Microsoft Windows NT® Active Directory™ Service Interfaces (ADSI) OLE DB Provider。
Transact-SQL 子集
如果提供程序支持所需的 OLE DB 接口,下列 Transact-SQL 語句類別都可以用于分布式查詢。 除了將遠程表作為目的表的 SELECT INTO 語句外,其他所有的 SELECT 語句都可以使用。
如果提供程序支持插入操作所需的接口,INSERT 語句可以用于遠程表。有關 INSERT 語句的 OLE DB 要求的詳細信息,請查閱本文后面的INSERT 語句。
如果提供程序滿足 OLE DB 接口在特定表上的要求,UPDATE 和 DELETE 語句也可以用于遠程表。有關更新或刪除遠程表時 OLE DB 接口必須滿足的要求和條件,請參閱本文后面的UPDATE 和 DELETE 語句。
游標支持
如果提供程序支持所需的 OLE DB 功能,則分布式查詢支持快照和鍵集兩種游標。分布式查詢不支持動態(tài)游標。用戶請求的分布式查詢的動態(tài)游標將自動降級為鍵集游標。
快照游標在游標打開時被寫入,而且結果集保持不變;對基本表的更新、插入和刪除操作不會反映到游標中。
鍵集游標在游標打開時被寫入,而且結果集在游標的整個生存期中保持不變。但是,如果更新或刪除基本表中的行,當訪問這些行時,能夠在游標中看到變化。如果對基本表的插入操作可能影響游標成員,則這種變化則是不可見的。
如果提供程序滿足更新和刪除遠程表的條件,則可以通過使用分布式查詢中定義的游標以及對遠程表的引用來更新和刪除遠程表,例如:table UPDATE | DELETE <遠程表> WHERE CURRENT OF <游標名稱>。有關詳細信息,請參閱本文后面的UPDATE 和 DELETE 語句。
支持鍵集游標的要求
如果滿足所有 Transact-SQL 語法的條件,而且滿足以下兩種情況之一,那么在分布式查詢中就支持鍵集游標: 在查詢中,OLE DB 提供程序支持所有遠程表上的可重用書簽。可重用書簽可以從給定表的某個行集中隱去,然后用于同一表中的其他行集上。對可重用書簽的支持是通過 IDBSchemaRowset 的 TABLES_INFO 架構行集來指定的,方法是將 BOOKMARK_DURABILITY 列設置為 BMK_DURABILITY_INTRANSACTION 或某種更高的持久性。
所有的遠程表都通過 IDBSchemaRowset 接口的 INDEXES 行集來列出唯一鍵。應該存在一個索引項,其中的 UNIQUE 列設置為 VARIANT_TRUE。
包含 OpenQuery 函數(shù)的分布式查詢不支持鍵集游標。
支持可更新鍵集游標的要求
通過在分布式查詢上定義的鍵集游標,可以更新或刪除遠程表,例如:UPDATE | DELETE <遠程表> WHERE CURRENT OF <游標名稱>。下面是在分布式查詢中允許使用可更新游標的條件: 如果提供程序也滿足對遠程表進行更新和刪除操作的條件,就允許使用可更新游標。有關詳細信息,請參閱本文后面的UPDATE 和 DELETE 語句。
所有的可更新鍵集游標操作必須位于使用可復讀或更高的隔離級別的用戶定義事務中。此外,提供程序必須以 ITransactionJoin 接口支持分布式事務處理。
OLE DB 提供程序交互階段
所有分布式查詢的執(zhí)行方案都有六種操作: 建立連接和檢索屬性操作,指定 SQL Server 連接 OLE DB 提供程序的方法以及將用到提供程序的哪些屬性。
表名解析和檢索元數(shù)據(jù)操作,指定 SQL Server 將遠程表名稱(指定時使用兩種方法之一:基于鏈接服務器的名稱或特殊名稱)解析為提供程序中相應數(shù)據(jù)對象的方法。這也包括 SQL Server 為編譯和優(yōu)化分布式查詢從提供程序檢索的表元數(shù)據(jù)。
事務管理操作,指定所有與 OLE DB 提供程序的事務相關的交互。
數(shù)據(jù)類型處理操作,該操作指定在執(zhí)行分布式查詢過程中,當 SQL Server 從 OLE DB 提供程序獲得數(shù)據(jù)或向其導出數(shù)據(jù)時 SQL Server 處理 OLE DB 數(shù)據(jù)類型的方法。
錯誤處理操作,指定 SQL Server 使用從提供程序獲得的擴展錯誤信息的方法。
安全性操作,指定 SQL Server 安全性和提供程序安全性的交互方式。
建立連接和檢索屬性
SQL Server 使用 OPENROWSET 功能支持兩種遠程數(shù)據(jù)對象命名協(xié)議:基于鏈接服務器的四段式名稱和特殊名稱。
基于鏈接服務器的名稱
鏈接服務器是對 OLE DB 數(shù)據(jù)源的抽象?;阪溄臃掌鞯拿Q分為四段:<鏈接服務器>.<目錄>.<架構>.<對象>,其中 <鏈接服務器> 是鏈接服務器的名稱。SQL Server 將 <鏈接服務器> 視為 OLE DB 提供程序和連接屬性(用于向提供程序標識數(shù)據(jù)源)的來源。其他三個名稱段被 OLE DB 數(shù)據(jù)源解釋為對特定遠程表的標識。
特殊名稱
特殊名稱是基于 OPENROWSET 或 OPENDATASOURCE 函數(shù)的名稱。它包括在分布式查詢中每次引用遠程表時的所有連接信息(包括所使用的 OLE DB 提供程序、用于標識數(shù)據(jù)源的屬性、用戶 ID 和密碼)。
默認情況下,只允許系統(tǒng)管理員使用特殊名稱。要使用基于 OLE DB 提供程序的特殊名稱,應將提供程序的 DisallowAdhocAccess 選項設置為 0。
如果使用鏈接服務器名稱,SQL Server 將在鏈接服務器定義中為 OLE DB 提供程序提取提供程序的名稱和初始化屬性。如果使用特殊名稱,SQL Server 將從 OPENROWSET 函數(shù)的參數(shù)中提取相同的信息。
有關使用四段式名稱建立鏈接服務器和基于特殊名稱的語法的詳細說明,請參閱 SQL Server Books Online。
連接 OLE DB 提供程序
以下是 SQL Server 連接 OLE DB 提供程序時執(zhí)行的高級步驟。 SQL Server 創(chuàng)建數(shù)據(jù)源對象。 SQL Server 使用提供程序的 ProgID 來建立數(shù)據(jù)源對象 (DSO) 的實例。ProgID 被指定為鏈接服務器配置信息的 provider_name 參數(shù),或在使用特殊名稱時被指定為 OPENROWSET 函數(shù)的第一個參數(shù)。
SQL Server 通過 OLE DB 服務組件接口 IDataInitialize 創(chuàng)建提供程序的 DSO 實例。這使服務組件管理器可以在提供程序的本地功能上集成其服務(例如回滾和支持更新)。另外,通過 IDataInitialize 建立提供程序的實例還允許 OLE DB 服務組件為它們提供連接池,這樣可減少連接和初始化的開銷。
在 SQL Server 的進程中還是在一個獨立的進程中創(chuàng)建給定提供程序的實例,可以根據(jù)需要進行配置。在獨立的進程中創(chuàng)建實例能夠保護 SQL Server 進程免受提供程序故障的影響。但同時還存在著與在 SQL Server 進程外組織 OLE DB 調用有關的性能開銷。通過設置提供程序選項 Allow In Process,可以將提供程序配置為進程內(nèi)實例或進程外實例。有關設置提供程序選項的詳細信息,請參閱 SQL Server Books Online。
要學習更多有關 OLE DB 服務組件和建立會話池的知識,請參閱提供程序的 OLE DB 文檔。
初始化數(shù)據(jù)源。 創(chuàng)建 DSO 之后,如果服務器的配置選項 remote login timeout 大于 0,IDBProperties 接口將設置 DBPROP_INIT_TIMEOUT 初始化屬性;該屬性為必需的屬性。
如果在鏈接服務器定義或 OPENROWSET 函數(shù)的第二個參數(shù)中指定或隱含了下列屬性,則它們將被設置:
DBPROP_INIT_PROVIDERSTRING
DBPROP_INIT_DATASOURCE
DBPROP_INIT_LOCATION
DBPROP_INIT_CATALOG
DBPROP_AUTH_USERID
DBPROP_AUTH_PASSWORD
設置了這些屬性后,將調用 IDBInitialize::Initialize 以指定的屬性初始化 DSO。
SQL Server 收集特定提供程序的信息。 SQL Server 將收集若干用于分布式查詢執(zhí)行中的提供程序屬性;這些屬性將通過調用 IDBProperties::GetProperties 來檢索。這些屬性全都是可選的;但是,對所有相關屬性的支持將允許 SQL Server 充分利用提供程序的功能。例如,在確定 SQL Server 是否能夠向提供程序發(fā)送查詢時,需要使用 DBPROP_SQLSUPPORT。如果提供程序不支持該屬性,SQL Server 就不能將遠程提供程序用作 SQL 命令提供程序,即使它是一個 SQL 命令提供程序。在下表(表 1)中,“默認值”列列出了在提供程序不支持該屬性時 SQL Server 所采用的值。
表 1:SQL Server OLE-DB 提供程序采用的屬性
屬性 默認值 用法
DBPROP_DBMSNAME 無 用于錯誤信息。
DBPROP_DBMSVER 無 用于錯誤信息。
DBPROP_PROVIDERNAME 無 用于錯誤信息。
DBPROP_PROVIDEROLEDBVER 1.5 用于確定 2.0 功能的可用性。
DBPROP_CONCATNULLBEHAVIOR 無 用于確定提供程序的 NULL 連接行為是否與 SQL Server 一致。
DBPROP_NULLCOLLATION 無 只有在 NULLCOLLATION 符合 SQL Server 的 Null 排序規(guī)則時才允許排序/使用索引。
DBPROP_OLEOBJECTS 無 確定提供程序是否支持大數(shù)據(jù)對象列的結構化存儲接口。
DBPROP_STRUCTUREDSTORAGE 無 確定支持哪種用于大對象類型的結構化存儲接口( ILockBytes、Istream 和 ISequentialStream 三種接口之一)。
DBPROP_MULTIPLESTORAGEOBJECTS False 確定是否支持同時打開一個以上的大對象列。
DBPROP_SQLSUPPORT 無 確定是否能夠向提供程序發(fā)送 SQL 查詢。
DBPROP_CATALOGLOCATION DBPROPVAL_CL_START 用于構造多段表名。
SQLPROP_DYNAMICSQL False SQL Server 特有的屬性:如果返回 VARIANT_TRUE,則指示參數(shù)標記 ‘?‘ 可以用于參數(shù)化查詢執(zhí)行。
SQLPROP_NESTEDQUERIES False SQL Server 特有的屬性:如果返回 VARIANT_TRUE,則指示提供程序在 FROM 子句中支持嵌套的 SELECT 語句。
SQLPROP_GROUPBY False SQL Server 特有的屬性:如果返回 VARIANT_TRUE,則指示提供程序支持在 SELECT 語句中使用 GROUP BY 子句(如 SQL-92 標準所規(guī)定的一樣)。
SQLPROP_DATELITERALS False SQL Server 特有的屬性:如果返回 VARIANT_TRUE,則指示提供程序支持各 SQL Server Transact-SQL 語法所規(guī)定的日期時間文字。
SQLPROP_ANSILIKE False SQL Server 特有的屬性:該屬性對支持 SQL-Minimum 級別的提供程序比較有意義,并且它支持各 SQL-92 entry 級別所規(guī)定的 LIKE 運算符(使用 ‘%‘ 和 ‘_‘ 作為通配符)。
SQLPROP_SUBQUERIES False SQL Server 屬性:該屬性對支持 SQL-Minimum 級別的提供程序比較有意義。它指示提供程序支持 SQL-92 Entry 級別所規(guī)定的子查詢。包括 SELECT 序列和 WHERE 子句中的子查詢(支持相關子查詢以及 IN、EXISTS、ALL 和 ANY 運算符)。
SQLPROP_INNERJOIN False SSQL Server 特有的屬性:該屬性對支持 SQL-Minimum 級別的提供程序比較有意義。它指示支持在 FROM 子句中使用多表的聯(lián)接。
下面是從 IDBInfo::GetLiteralInfo 檢索到的三個文字:DBLITERAL_CATALOG_SEPARATOR、DBLITERAL_SCHEMA_SEPARATOR(用于根據(jù)給定的目錄、架構和對象名構造完整的對象名稱)和 DBLITERAL_QUOTE(用于引用發(fā)送到提供程序的 SQL 查詢中的標識符名稱)。
如果提供程序不支持分隔符文字,SQL Server 將使用句點 (.) 作為默認的分隔符字符。如果提供程序只支持目錄分隔符字符而不支持架構分隔符字符,則 SQL Server 將把目錄分隔符字符也作為架構分隔符字符使用。如果提供程序不支持 DBLITERAL_QUOTE,SQL Server 將使用單引號 (‘) 作為引用字符。
注意:    如果提供程序的名稱分隔符文字和這些默認值不匹配,提供程序必須使用 IDBInfo 將它們公開,以便 SQL Server 通過四段式名稱訪問它的表。如果沒有將這些文字公開,那么對于這樣的提供程序將只能使用傳遞查詢。
表名解析和元數(shù)據(jù)檢索
SQL Server 將分布式查詢中給定的遠程表名稱解析為 OLE DB 數(shù)據(jù)源中的特定表或視圖。基于鏈接服務器的和特殊的命名架構都將導致提供程序將名稱解釋為三段式名稱。在使用基于鏈接服務器的名稱時,四段式名稱的后三部分形成目錄、架構和對象名。在使用特殊名稱時,OPENROWSET 函數(shù)的第三個參數(shù)指定了說明目錄、架構和對象名的三段式名稱。目錄和架構名稱中可以有一個為空值或全部為空值。(當目錄名和架構名為空時,四段式名稱將變成:<服務器名稱>...<對象名稱>。)在此情況下,SQL Server 搜索架構行集表時將使用 NULL 作為對應的值。
SQL Server 使用的名稱解析規(guī)則和元數(shù)據(jù)檢索的步驟取決于提供程序是否支持 Session 對象的 IDBSchemaRowset 接口。
如果支持 IDBSchemaRowset,則使用 IDBSchemaRowset 接口中的 TABLES、COLUMNS、INDEXES 和 TABLES_INFO 架構行集。(TABLES_INFO 架構行集在 OLE DB 2.0 中定義。)SQL Server 通過限制 IDBSchemaRowset 接口返回的架構行集來尋找與特定遠程表名稱部分匹配的架構行。下面是與提供程序支持的架構行集限制有關的規(guī)則,以及 SQL Server 使用這些規(guī)則來檢索遠程表元數(shù)據(jù)的方法: 對 TABLE_NAME 和 COLUMN_NAME 列的限制總是必要的。
如果提供程序支持對 TABLE_CATALOG(或 TABLE_SCHEMA)的限制,SQL Server 將使用對 TABLE_CATALOG(或 TABLE_SCHEMA)的限制。如果在遠程表名中沒有指定目錄(或架構)名稱,則使用 NULL 值作為相應的限制值。如果指定了目錄(或架構)名稱,提供程序必須支持對 TABLE_CATALOG(或 TABLE_SCHEMA)的相應限制。
提供程序必須全部支持對 TABLES 和 COLUMNS 中的 TABLE_SCHEMA 列的限制,或者全部不支持。提供程序必須全部支持對 TABLES 和 COLUMNS 的目錄名稱限制,或者全部不支持。
如果支持 INDEXES 上的任何限制,提供程序必須全部支持對 TABLES 和 INDEXES 的架構限制,或者全部不支持。提供程序必須全部支持對 TABLES 和 INDEXES 行集的目錄名限制,或者全部不支持。
從 TABLES 架構行集中,通過按上述規(guī)則設置限制,SQL Server 可檢索 TABLE_CATALOG、TABLE_SCHEMA、TABLE_NAME、TABLE_TYPE 和 TABLE_GUID 列。
從 COLUMNS 架構行集中,SQL Server 可檢索 TABLE_CATALOG、TABLE_SCHEMA、TABLE_NAME、COLUMN_NAME、COLUMN_GUID、ORDINAL_POSITION、COLUMN_FLAGS、IS_NULLABLE、DATA_TYPE、TYPE_GUID、CHARACTER_MAXIMUM_LENGTH、NUMERIC_PRECISION 和 NUMERIC_SCALE 列。COLUMN_NAME、DATA_TYPE 和 ORDINAL_POSITION 必須返回有效的非空值。如果 DATA_TYPE 是 DBTYPE_NUMERIC 或 DBTYPE_DECIMAL,相應的 NUMERIC_PRECISION 和 NUMERIC_SCALE 也必須是有效的非空值。
從可選的 INDEXES 架構行集中,通過按原先規(guī)則設置限制,SQL Server 可在指定的遠程表上尋找索引。SQL Server 從找到的索引條目中檢索 TABLE_CATALOG、TABLE_SCHEMA、TABLE_NAME、INDEX_CATALOG、INDEX_SCHEMA、INDEX_NAME、PRIMARY_KEY、UNIQUE、CLUSTERED、FILL_FACTOR、ORDINAL_POSITION、COLUMN_NAME、COLLATION、CARDINALITY 和 PAGES 列。
從可選的 TABLES_INFO 行集中,SQL Server 尋找有關指定遠程表的附加信息(例如書簽支持、書簽類型和長度)。除了 TABLES_INFO 行集中的 DESCRIPTION 列以外,所有的列都被使用。TABLES_INFO 行集中的信息按如下要求使用: BOOKMARK_DURABILITY 列用于實現(xiàn)更有效的鍵集游標。如果該列的值為 BMK_DURABILITY_INTRANSACTION 或更高持久性的值,SQL Server 在實現(xiàn)鍵集游標時,將對遠程表行使用基于書簽的檢索和更新。
BOOKMARK_TYPE、BOOKMARK_DATA TYPE 和 BOOKMARK_MAXIMUM_LENGTH 列用于在編譯查詢時確定書簽的元數(shù)據(jù)。如果這些列不被支持,SQL Server 將在編譯時通過 IOpenRowset 打開基本表行集來獲得書簽信息。
如果不支持 IDBSchemaRowset 并且遠程表名稱包含了目錄或架構名,則 SQL Server 將要求 IDBSchemaRowset 并返回一個錯誤。但是,如果既沒有提供目錄名,也沒有提供架構名,SQL Server 將打開對應于遠程表的行集,并從行集對象的強制接口 IColumnsInfo 中檢索列元數(shù)據(jù)。
SQL Server 通過調用 IOpenRowset::OpenRowset 打開對應于表的行集。提供給 OPENROWSET 的表名是由目錄、架構和對象名等部分構成的。 名稱的每個部分(目錄、架構、對象名)都使用提供程序的引用符 (DBLITERAL_QUOTE) 引用,然后使用 DBLITERAL_CATALOG_SEPARATOR 字符和 DBLITERAL_SCHEMA_SEPARATOR 字符連接到一起。名稱的構造遵循 IOpenRowset 中的 OLE DB 規(guī)則。
在行集對象打開后,可通過 IColumnsInfo::GetColumnInfo 檢索表中的列元數(shù)據(jù)。
如果 IDBSchemaRowset 不支持 TABLES、COLUMNS 和 TABLES_INFO 行集,SQL Server 將打開兩次基本表上的行集:在查詢編譯時打開一次來檢索元數(shù)據(jù),在查詢運行時再打開一次。由于打開行集而受影響的提供程序(例如,運行更改實時設備狀態(tài)的代碼,發(fā)送電子郵件,運行任意用戶提供的代碼)必須注意這種行為。
檢索統(tǒng)計信息
如果提供程序支持基本表上的分布式統(tǒng)計,那么 SQL Server 2000 將使用這些統(tǒng)計。有兩種統(tǒng)計可用于 SQL Server 查詢處理器: 列(或元組)基數(shù):它是在一個表的列(或一組列)中唯一值的數(shù)目??捎糜谝罁?jù)列評估謂詞的選擇性。支持分布式統(tǒng)計的提供程序必須支持至少一種基數(shù)。
柱狀圖:如果值的分布不均勻,則唯一值的數(shù)目對于評估謂詞的選擇性是不夠充分的。在此情況下,提供一個柱狀圖即可就表中列值的分布提供更好的圖形化信息。
有了統(tǒng)計就能使 SQL Server 查詢優(yōu)化程序更好地評估一個查詢中的中間操作的基數(shù),這將使它生成更好的執(zhí)行方案。
OLE DB 提供程序應支持以下分布式統(tǒng)計: 強制:支持屬性 (1) DBPROP_TABLESTATISTICS,該屬性指示是否支持列或元組基數(shù)以及是否支持柱狀圖;和屬性 (2) DBPROP_OPENROWSETSUPPORT,該屬性使用 DBPROPVAL_ORS_HISTOGRAM 位來指示是否支持柱狀圖。
強制:TABLE_STATISTICS 架構行集。TABLE_STATISTICS 架構行集列出了給定數(shù)據(jù)庫中可用的統(tǒng)計。它也包含了架構行集本身的列或元組基數(shù),同時指示了特定列是否支持柱狀圖。為了使 SQL Server 能夠使用統(tǒng)計,此架構行集中的 TABLE_NAME、STATISTICS_NAME、STATISTICS_TYPE、COLUMN_NAME 和 ORDINAL_POSITION 列是強制的。COLUMN_CARDINALITY 或 TUPLE_CARDINALITY 中至少有一個是強制的。如果支持柱狀圖,則 NO_OF_RANGES 也是強制的。
可選:可選地,如果提供程序支持柱狀圖,它應支持 IOpenRowset::OpenRowset 方法的增強功能(允許通過指定相應統(tǒng)計的 DBID 來打開一個柱狀圖行集)。
有關統(tǒng)計接口的完整信息,請參閱 OLE DB 2.6 規(guī)范。
約束
如果 OLE DB 提供程序支持 OLE DB 2.6 的新架構行集 CHECK_CONSTRAINTS_BY_TABLE,SQL Server 2000 查詢優(yōu)化程序也可以使用遠程數(shù)據(jù)源中基本表上的 CHECK 約束。架構行集的 CHECK_CLAUSE 列將返回符合 SQL-92 語法的 CHECK 子句謂詞。查詢優(yōu)化程序使用約束信息來消除或簡化因表中約束的存在而總為真或總為假的謂詞。
事務管理
SQL Server 通過使用提供程序的 ITransactionLocal(用于本地事務)和 ITransactionJoin(用于分布式事務)OLE DB 接口支持以事務方式訪問分布式數(shù)據(jù)。通過啟動提供程序的本地事務,SQL Server 可保證單元寫操作。通過使用分布式事務,SQL Server 可確保包括多個節(jié)點的事務在所有節(jié)點中都有同樣的結果(無論是提交還是終止)。如果提供程序不支持必要的 OLE DB 事務相關接口,根據(jù)本地事務的環(huán)境將不允許針對該提供程序進行更新操作。
下表(表 2)描述了在用戶執(zhí)行分布式查詢(給定了提供程序的功能和本地事務的環(huán)境)時發(fā)生的事情。針對提供程序的讀操作是指一條 SELECT 語句,或者指遠程表用在 SELECT INTO、INSERT、UPDATE 或 DELETE 語句的輸入端的情形。針對提供程序的寫操作是指 INSERT、UPDATE 或 DELETE 語句,其中遠程表作為目的表。
表 2:基于提供程序的功能和事務環(huán)境的分布式查詢結果。
分布式查詢
發(fā)生 提供程序不
支持
ITransactionLocal 提供程序同時支持
ItransactionLocal
但不支持
ITransactionJoin 提供程序同時支持
ItransactionLocal
ITransactionJoin
在自身事務中(非用戶事務)。 默認情況下,只允許讀操作。如果啟用提供程序級選項 Nontransacted Updates,則允許寫操作。(當啟用該選項時,SQL Server 不能保證提供程序數(shù)據(jù)的原子性和一致性。這將導致寫操作的影響部分地反映到遠程數(shù)據(jù)源中,而且無法撤消。) 所有語句都允許在遠程數(shù)據(jù)上運行。鍵集游標是只讀的。
本地事務在提供程序上以當前 SQL Server 會話隔離級別啟動,然后在語句運行成功后提交。(除非使用 SET TRANSACTION ISOLATION LEVEL 對 SQL Server 會話的隔離級別進行修改,否則默認級別是 READ COMMITTED。提供程序必須支持請求的隔離級別。) 允許所有語句。鍵集游標是只讀的。
本地事務在提供程序上以當前 SQL Server 會話隔離級別啟動,然后在語句運行成功后提交。
在用戶事務中(也就是說,發(fā)生在 BEGIN TRAN 或 BEGIN DISTRIBUTED TRAN 和 COMMIT 之間)。 如果事務的隔離級別是 READ COMMITTED(默認值)或更低,則允許讀操作。
如果隔離級別更高,將不允許分布式查詢。
只允許讀操作。
新的分布式事務在提供程序上以當前 SQL Server 會話隔離級別啟動。
允許所有語句。
新的分布式事務在提供程序上以當前 SQL Server 會話隔離級別啟動,然后在用戶事務提交時提交。對于修改數(shù)據(jù)的語句,默認情況下,SQL Server 將在分布式事務下啟動一個嵌套的事務,這樣出現(xiàn)某種錯誤時就可以停止修改數(shù)據(jù)語句,而不必停止周圍的事務。如果 XACT_ABORT SET 選項為打開狀態(tài),SQL Server 就不需要嵌套事務支持,而且在修改數(shù)據(jù)的語句出錯時可停止周圍的事務。
分布式查詢中數(shù)據(jù)類型的處理
OLE DB 提供程序按照由 OLE DB 定義的數(shù)據(jù)類型(由 OLE DB 的 DBTYPE 指示)表明它們的數(shù)據(jù)。SQL Server 在服務器中以本地的 SQL Server 類型處理外部數(shù)據(jù);不管數(shù)據(jù)是被 SQL Server 使用還是從 SQL Server 導出,這種處理方式都會產(chǎn)生從 OLE DB 數(shù)據(jù)類型到 SQL Server 本地數(shù)據(jù)類型的映射(見表 3)或者從 SQL Server 本地數(shù)據(jù)類型到 OLE DB 數(shù)據(jù)類型的映射。這種映射是以隱含方式實現(xiàn)的,除非另外注明。
分布式查詢中的數(shù)據(jù)類型使用下列兩種映射方式之一進行處理: 使用端映射,當遠程表出現(xiàn)在 SELECT 語句中并位于 INSERT、UPDATE 和 DELETE 語句的輸入端時,該映射在使用端將類型從 OLE DB 數(shù)據(jù)類型映射為 SQL Server 本地數(shù)據(jù)類型。
導出端映射,當遠程表作為 INSERT 或 UPDATE 語句的目的表出現(xiàn)時,該映射在導出端將類型從 SQL Server 數(shù)據(jù)類型映射為 OLE DB 數(shù)據(jù)類型。
表 3:SQL Server 和 OLE-DB 數(shù)據(jù)類型映射表。
OLE DB 類型 DBCOLUMNFLAG SQL Server 數(shù)據(jù)類型
DBTYPE_I1*   numeric(3,0)
DBTYPE_I2   smallint
DBTYPE_I4   int
DBTYPE_I8   numeric(19,0)
DBTYPE_UI1   tinyint
DBTYPE_UI2*   numeric(5,0)
DBTYPE_UI4*   numeric(10,0)
DBTYPE_UI8*   numeric(20,0)
DBTYPE_R4   float
DBTYPE_R8   real
DBTYPE_NUMERIC   numeric
DBTYPE_DECIMAL   decimal
DBTYPE_CY   money
DBTYPE_BSTR DBCOLUMNFLAGS_ISFIXEDLENGTH=true
或最大長度大于 4000 個字符 ntext
DBTYPE_BSTR DBCOLUMNFLAGS_ISFIXEDLENGTH=true nchar
DBTYPE_BSTR DBCOLUMNFLAGS_ISFIXEDLENGTH=false nvarchar
DBTYPE_IDISPATCH   Error
DBTYPE_ERROR   Error
DBTYPE_BOOL   bit
DBTYPE_VARIANT*   nvarchar
DBTYPE_IUNKNOWN   Error
DBTYPE_GUID   uniqueidentifier
DBTYPE_BYTES DBCOLUMNFLAGS_ISLONG=true 或最大長度大于 8000 image
DBTYPE_BYTES DBCOLUMNFLAGS_ISROWVER=true,
DBCOLUMNFLAGS_ISFIXEDLENGTH=true、
列大小等于 8 或未報告最大長度。 timestamp
DBTYPE_BYTES DBCOLUMNFLAGS_ISFIXEDLENGTH=true binary
DBTYPE_BYTES DBCOLUMNFLAGS_ISFIXEDLENGTH=true varbinary
DBTYPE_STR DBCOLUMNFLAGS_ISFIXEDLENGTH=true char
DBTYPE_STR DBCOLUMNFLAGS_ISFIXEDLENGTH=true varchar
DBTYPE_STR DBCOLUMNFLAGS_ISLONG=true 或最大長度大于 8000 個字符或未報告最大長度。 text
DBTYPE_WSTR DBCOLUMNFLAGS_ISFIXEDLENGTH=true nchar
DBTYPE_WSTR DBCOLUMNFLAGS_ISFIXEDLENGTH=false nvarchar
DBTYPE_WSTR DBCOLUMNFLAGS_ISLONG=true 或 最大長度大于 4000 個字符或未報告最大長度。 ntext
DBTYPE_UDT   Error
DBTYPE_DATE*   datetime
DBTYPE_DBDATE   datetime(必須顯式轉換)
DBTYPE_DBTIME   datetime(必須顯式轉換)
DBTYPE_DBTIMESTAMP*   datetime
DBTYPE_ARRAY   Error
DBTYPE_BYREF   Ignored
DBTYPE_VECTOR   Error
DBTYPE_RESERVED   Error
* 表示如果 SQL Server 中沒有確切的等價數(shù)據(jù)類型,則轉換為某種形式的 SQL Server 類型。這種轉換將導致精確度降低、上溢或下溢。如果 SQL Server 的未來版本支持相應的數(shù)據(jù)類型,則默認的隱式映射可能會改變。
注意: numeric(p,s) 表示 SQL Server 的數(shù)據(jù)類型 numeric 精度為 p,刻度為 s 。對于 DBTYPE_NUMERIC 和 DBTYPE_DECIMAL,允許使用的最大精度為 38。創(chuàng)建訪問器時,提供程序必須支持以 DBTYPE_WSTR 綁定到 DBTYPE_BSTR 列。DBTYPE_VARIANT 列當作 Unicode 字符串 nvarchar 使用。這需要提供程序支持從 DBTYPE_VARIANT 向 DBTYPE_WSTR 的轉換。提供程序應按照 OLE DB 的定義實現(xiàn)該轉換。有關詳細信息,請參閱附錄 A:SQL Server 采用的 OLE DB 接口。
解釋數(shù)據(jù)類型映射
是否映射對 SQL Server 類型由 OLE DB 數(shù)據(jù)類型和描述該列或數(shù)量值的 DBCOLUMNFLAGS 值共同確定。在使用 COLUMNS 架構行集時,由 DATA_TYPE 和 COLUMN_FLAGS 列來代表這些值。在使用 IColumnsInfo::GetColumnInfo 接口時,由 DBCOLUMNINFO 結構的 wType 和 dwFlags 成員代表這些信息。
若要在包括特定的 DBTYPE 和 DBCOLUMNFLAG 值的給定列上用使用端映射,應在該表中尋找相應的 SQL Server 類型。在表達式中遠程表的列的類型規(guī)則可以通過如下的簡單規(guī)則描述:
給定遠程列的值在 Transact-SQL 表達式中是合法的條件為,它在上表中所映射的 SQL Server 類型在相同的上下文中是合法的。
表和規(guī)則定義: 比較和表達式。 通常,如果 <op> 是可用于 X 數(shù)據(jù)類型和 <遠程列> 所映射數(shù)據(jù)類型上的有效運算符,則 X <op> <遠程列> 就是一個有效表達式。
顯式轉換。 允許 Convert (X, <遠程列>) 的條件:<遠程列> 的 DBTYPE 映射為本地數(shù)據(jù)類型 Y(如上表所示)而且允許從 Y 到 X 的顯式轉換。
如果用戶要將遠程數(shù)據(jù)轉換為非默認本地數(shù)據(jù)類型,則必須使用顯示轉換。
若要在對遠程表使用 UPDATE 和 INSERT 語句時使用導出端映射,應使用同樣的表將本地的 SQL Server 數(shù)據(jù)類型映射為 OLE DB 數(shù)據(jù)類型。如果下述情況之一存在,則允許將 SQL Server 類型 (S1) 映射為給定的 OLE DB 類型 (T): 相應的映射可以在映射表(表 3)中直接找到。
允許 S1 隱式轉換為另一種 SQL Server 類型 S2,而 S2 對類型 T 的映射包含在映射表(表 3)中。
大對象 (LOB) 的處理
如映射表(表 3)中所述,如果 DBTYPE_STR、DBTYPE_WSTR 或 DBTYPE_BSTR 類型的列也報告 DBCOLUMNFLAGS_ISLONG,或者它們的最大長度超過 4,000 個字符(或未報告最大長度),SQL Server 將相應把它們處理為 text 或 ntext 列。類似地,對于 DBTYPE_BYTES 列,如果設置了 DBCOLUMNFLAGS_ISLONG,或最大長度大于 8,000 個字節(jié)(或未報告最大長度),該列將被視為 image 列。Text、ntext 和 image 列稱為 LOB 列。
SQL Server 不會在 OLE DB 提供程序的 LOB 上列出完整的文本或圖像功能。在 OLE DB 提供程序的大對象上不支持 TEXTPTRS 的;因此,也不支持相關的功能,例如,TEXTPTR 系統(tǒng)函數(shù)以及 READTEXT、WRITETEXT 和 UPDATETEXT 語句。支持檢索整個 LOB 列的 SELECT 語句,也支持對遠程表上整個大對象列的 UPDATE 和 INSERT 語句。
如果提供程序支持 LOB 列上的結構化存儲接口,SQL Server 將使用它們。結構化存儲接口如下所示(按優(yōu)先權和功能的遞增順序排列):ISequentialStream、Istream 和 ILockBytes。如果提供程序支持這些接口中的一個或多個,當通過 IDBProperties 接口查詢提供程序時,它必須將 DBPROPVAL_OO_BLOB 作為 DBPROP_OLEOBJECTS 屬性的值返回。同樣,提供程序應在 DBPROP_STRUCTUREDSTORAGE 屬性中指出它所支持的接口。
如果提供程序不支持 LOB 列上的任何結構化存儲接口,SQL Server 2000 將在自身實現(xiàn)該接口,同時仍將它們按 text、ntext 或 image 列列出。
訪問 LOB 列
如果提供程序支持結構化存儲接口之一,SQL Server 在查詢運行時按如下步驟檢索 LOB 列: 在通過 IOpenRowset::OpenRowset 打開行集合前,SQL Server 請求對大對象列上的一個或多個結構化存儲接口(ISequentialStream、Istream 和 ILockBytes)的支持。提供程序支持的第一個接口是必需的;而其他接口則是可選的,可通過將 DBPROP 結構的 dwOptions 元素設置為 DBPROPOPTIONS_SETIFCHEAP 來請求它們。例如,如果提供程序同時支持 ISequentialStream 和 ILockBytes ,則 ISequentialStream 是必需的,而 ILockBytes 則是可選的。
打開行集后,SQL Server 使用 IRowsetInfo::GetProperties 來識別行集中可用的實際接口。提供程序返回的最后一個或最優(yōu)先接口將被使用。當 SQL Server 創(chuàng)建基于大對象列的訪問器時,該列綁定為 DBTYPE_IUNKNOWN,綁定中 DBOBJECT 結構的 iid 元素設置為接口。
讀取 LOB 列
使用被請求的結構化存儲接口的接口指針(在 IRowset::GetData 生成的行緩沖區(qū)中返回)來讀取大對象列。如果提供程序不支持同時打開多個 LOB(即不支持 DBPROP_MULTIPLE_STORAGEOBJECTS)并且該行有多個大對象列時,SQL Server 將把 LOB 復制到本地工作表中。
在 LOB 列上的 UPDATE 和 INSERT 語句
SQL Server 通過向提供程序傳遞一個指向新的存儲對象的指針來修改存儲對象,而不使用提供程序所提供的接口。對于每個 LOB 列,存儲對象上被更新或插入的值是使用選定的結構化存儲接口創(chuàng)建的。根據(jù)操作是 UPDATE 還是 INSERT,指向存儲對象的指針分別通過 IRowsetChange::SetData 或 IRowsetChange::InsertRow 傳遞到提供程序。
錯誤處理
如果對 OLE DB 提供程序特定方法的調用返回錯誤代碼,SQL Server 將查找提供程序的擴展錯誤信息,然后將有關錯誤條件的信息返回給用戶。
SQL Server 使用由 OLE DB 指定的 OLE DB 錯誤對象。其中的高級步驟有: 如果方法調用返回來自提供程序的錯誤代碼,SQL Server 將查找 ISupportErrorInfo 接口。如果支持該接口,SQL Server 將調用 ISupportErrorInfo::InterfaceSupportsErrorInfo 來驗證生成錯誤代碼的接口是否支持該錯誤對象。
如果接口支持該錯誤對象,SQL Server 將調用 GetErrorInfo 函數(shù)來獲得一個指向當前錯誤對象的 IErrorInfo 接口指針。
SQL Server 使用 IErrorInfo 接口獲得指向 IErrorRecords 接口的指針。
SQL Server 使用 IErrorRecords 來循環(huán)查找對象中的所有錯誤記錄并獲得對應于每個記錄的錯誤信息文本。
有關如何使用提供程序的錯誤對象的詳細信息,請參閱 OLE DB 文檔。
安全性
當使用者連接到 OLE DB 提供程序時,通常情況下,除非使用者希望作為集成安全用戶被驗證,否則提供程序將需要用戶 ID 和密碼。在分布式查詢中,SQL Server 將作為 OLE DB 提供程序的使用者(代表執(zhí)行分布式查詢的 SQL Server 登錄)。SQL Server 將當前的 SQL Server 登錄映射為鏈接服務器上的用戶 ID 和密碼。
這些映射可以被用戶指定用于給定的鏈接服務器,并可以通過系統(tǒng)存儲過程 sp_addlinkedsrvlogin 和 sp_droplinkedsrvlogin 來建立并管理。通過使用 IDBProperties::SetProperties 來建立初始化組屬性 DBPROP_AUTH_USERID 和 DBPROP_AUTH_PASSWORD,由映射確定的用戶 ID 和密碼可在連接建立的過程中傳遞到提供程序。
當客戶端通過 Microsoft® Windows NT® 的身份驗證連接到 SQL Server 時,如果登錄使用 sp_addlinkedsrvlogin 建立自身的映射,那么 SQL Server 在連接建立的過程中將嘗試模擬客戶端的安全上下文并設置提供程序的 DBPROP_AUTH_INTEGRATED 屬性。此過程稱為“委派”。只有 Windows® 2000 完全支持委派。在 Windows NT 4.0 或更早版本中,只有提供程序完全位于 SQL Server 機器中并且沒有通過網(wǎng)絡連接到后端數(shù)據(jù)源時才支持委派。在這種情況下,Windows NT 已驗證的登錄必須映射為特定的用戶 ID 和密碼才能訪問鏈接服務器。
在確定了用于連接的安全上下文后,OLE DB 提供程序將全面負責安全上下文的驗證以及對數(shù)據(jù)源中數(shù)據(jù)對象的權限檢查。
有關 sp_addlinkedsrvlogin 和 sp_droplinkedsrvlogin 的詳細信息,請參閱 SQL Server Books Online。
查詢執(zhí)行方案
執(zhí)行分布式查詢時,SQL Server 與 OLE DB 提供程序進行交互有下述一個或多個方案: 遠程查詢
索引訪問
單純表掃描
UPDATE 和 DELETE 語句
INSERT 語句
傳遞查詢
遠程查詢
SQL Server 生成一個 SQL 查詢,它將計算出由提供程序完整執(zhí)行的初始查詢的一部分。該方案只能用于 SQL 命令提供程序。SQL Server 通過生成 SQL 查詢將操作轉給提供程序的程度取決于提供程序支持的 SQL 語法。提供程序應通過如下方式指出它的 SQL 支持級別: 通過 DBPROP_SQLSUPPORT 屬性指出 SQL Minimum、ODBC Core 或 SQL-92 Entry 級別。SQL Minimum 語法級別是 SQL Server 2000 支持的新級別,它允許 SQL Server 向支持 SQL 簡單子集的簡單提供程序發(fā)送遠程查詢。該級別包含基本 SELECT 語句,即不包括子查詢、在 FROM 子句中使用多表(因此無聯(lián)接)和 GROUP BY 的 SELECT 語句。有關 SQL Server 用來為各語法級別的提供程序生成遠程查詢的 SQL 語法的子集的詳細信息,請參閱附錄 B:用于生成遠程查詢的 SQL 子集。
通過支持各種 SQL Server 特有的屬性來指出對個別 SQL 功能的支持,這些 SQL 功能沒有包括在 DBPROP_SQLSUPPORT 報告的語法級別中。在本節(jié)后面描述了屬性列表和 SQL Server 使用它們的方法。
SQL Server 在 Transact-SQL 字符串中使用問號 (?) 作為參數(shù)標記的帶參數(shù)查詢命令。帶參數(shù)查詢命令可以用于 SQL Server、Microsoft Jet 和 Oracle OLE DB 提供程序。對于其他提供程序,如果該提供程序支持 Command 對象的 ICommandWithParameters 屬性,并且至少滿足如下條件之一,則也可以使用帶參數(shù)查詢命令: 提供程序通過 DBPROP_SQLSUPPORT 屬性指出支持 SQL Server 的 ODBC Core 級別。
通過使用 IDBPProperties 支持 SQL Server 特有的屬性 SQLPROP_DYNCMICSQL,提供程序指出對問號 (?) 參數(shù)標記的支持。有關詳細信息,請參閱下一節(jié)“提供程序屬性”。
系統(tǒng)管理員通過設置提供程序上的選項 Dynamic Parameters 來使 SQL Server 生成帶參數(shù)查詢。
當 SQL Server 生成在遠程執(zhí)行的 SQL 文本時,表名和列名被提供程序的引用字符(IDBInfo 接口的 DBLITERAL_QUOTE 文字)引起來。如果不支持該文字,則表名和列名不會被引起來。
如果提供程序支持帶參數(shù)查詢執(zhí)行,SQL Server 將帶參數(shù)查詢執(zhí)行策略視為執(zhí)行一個遠程表和本地表的聯(lián)接。帶參數(shù)查詢根據(jù)由本地表中每一行生成的參數(shù)值重復執(zhí)行。這種策略減少了從提供程序獲取的行數(shù),并且有利于行數(shù)較少的本地表聯(lián)接到行數(shù)較多的遠程表。遠程聯(lián)接策略可以使用 REMOTE 聯(lián)接優(yōu)化提示來強制執(zhí)行。有關帶參數(shù)查詢執(zhí)行的詳細信息,請參閱 SQL Server Books Online。
下面是在遠程查詢方案中針對提供程序所進行的高級步驟: SQL Server 使用 IDBCreateCommand::CreateCommand 從 Session 對象創(chuàng)建 Command 對象。
如果將服務器配置選項 Remote Query Timeout 的值設置為大于零,SQL Server 將使用 ICommandProperties::SetProperties 把 Command 對象的 DBPROP_COMMANDTIMEOUT 設置為同樣的值;必須調用 ICommand::SetCommandText 來將命令文本設置為已生成的 Transact-SQL 字符串。
SQL Server 調用 ICommandPrepare::Prepare 來準備命令。如果提供程序不支持該接口,SQL Server 將繼續(xù)第 4 步。
如果生成的查詢是帶參數(shù)的,SQL Server 使用 ICommandWithParameters::SetParameterInfo 來描述這些參數(shù)并使用 IAccessor::CreateAccessor 創(chuàng)建使用這些參數(shù)的訪問器。
SQL Server 調用 ICommand::Execute 來執(zhí)行命令并創(chuàng)建行集。
SQL Server 使用 IRowset 接口瀏覽并使用表中的行。使用 IRowset::GetNextRows 獲取行,使用 IRowset::RestartPosition 來重定位行集的起始點,使用 IRowset::ReleaseRows 釋放行。
用于遠程查詢執(zhí)行的提供程序屬性
如果提供程序支持的 SQL 功能沒有包含在 DBPROP_SQLSUPPORT 報告的語法級別中,可以通過使用各種提供程序特有的屬性來指出它們。 SQLPROP_GROUPBY。該屬性對支持 SQL-Minimum 級別的提供程序比較有意義。它指出提供程序在 SELECT 語句中支持 GROUP BY 和 HAVING 子句。另外,它還指出提供程序支持如下五種聚合函數(shù):MIN、MAX、SUM、COUNT 和 AVG。提供程序可能不支持在這些合計函數(shù)參數(shù)中使用 DISTINCT。
SQLPROP_SUBQUERIES。該屬性對支持 SQL-Minimum 級別的提供程序比較有意義。它指出該提供程序支持 SQL-92 entry 級別所規(guī)定的子查詢。包括 SELECT 列表中的子查詢,以及 WHERE 子句中的關系子查詢,IN、EXISTS、ALL 和 ANY 運算符。
SQLPROP_DATELITERALS。該屬性對任何提供程序(包括支持 SQL-92 entry 級別的提供程序)都比較有意義。對日期時間文字的標準語法的支持不屬于 SQL-92 entry 級別。該 SQL Server 特有的屬性指出提供程序支持 SQL-92 標準所規(guī)定的日期時間文字語法。
SQLPROP_ANSILIKE。該屬性對支持 SQL-Minimum 級別的提供程序比較有意義。它指出提供程序支持每個 SQL-92 entry 級別所規(guī)定的 LIKE 運算符(使用 ‘%‘ 和 ‘_‘ 作為通配符)。由于 SQL-Minimum 級別沒有包括對 LIKE 的支持,所以它對支持 SQL-Minimum 級別的提供程序非常有用。
SQLPROP_INNERJOIN。該屬性對支持 SQL-Minimum 級別的提供程序比較有意義。它指出支持在 FROM 子句中使用多個表。由于 SQL-Minimum 級別不支持聯(lián)接,所以它對只支持 SQL-Minimum 級別的提供程序非常有用。但是,這并非指出了對顯式 JOIN 關鍵字和 OUT 聯(lián)接的支持。它只指出了支持在 FROM 子句使用多個表的隱含聯(lián)接。
SQLPROP_DYNAMICSQL。該屬性指出支持使用 ‘?‘ 作為參數(shù)標記。應支持參數(shù)標記在 WHERE 子句或 SELECT 列表中替代一個數(shù)量項目。對 ‘?‘ 運算符標記的支持允許 SQL Server 向提供程序發(fā)送帶參數(shù)查詢。
SQLPROP_NESTEDQUERIES。該屬性指出支持在 FROM 子句中嵌套 SELECT(例如,SELECT * FROM (SELECT * FROM T))。在多種情況下,SQL Server 在生成遠程執(zhí)行的查詢字符串時,在查詢的 FROM 子句中使用嵌套的 SELECT 語句。由于對嵌套 SELECT 的支持并不是 SQL-92 entry 級別所必需的,除非提供程序也設置了本屬性,否則 SQL Server 不會向提供程序委派帶有嵌套 SELECT 語句的查詢。另外,系統(tǒng)管理員也可以設置提供程序的 Nested Queries 選項,以使 SQL Server 生成用于提供程序上的嵌套查詢。
提供程序能夠通過使用名為 SQLPROPSET_OPTHINTS 的 SQL Server 特殊屬性集來支持這些屬性,并獲得已定義的 PROPID 值。屬性集 SQLPROPSET_OPTHINTS 和這兩個屬性通過使用以下常數(shù)來定義:
extern const GUID SQLPROPSET_OPTHINTS = { 0x2344480c, 0x33a7, 0x11d1,{ 0x9b, 0x1a, 0x0, 0x60, 0x8, 0x26, 0x8b, 0x9e } };enum SQLPROPERTIES {SQLPROP_NESTEDQUERIES = 0x4,SQLPROP_DYNAMICSQL = 0x5,SQLPROP_GROUPBY = 0x6,SQLPROP_DATELITERALS = 0x7,SQLPROP_ANSILIKE = 0x8,SQLPROP_INNERJOIN = 0x9,SQLPROP_SUBQUERIES = 0x10};隱含的字符集和排序順序
SQL Server 2000 支持在列級別上指定字符數(shù)據(jù)的排序。排序包括非 Unicode 字符數(shù)據(jù)(char 和 varchar 列)的字符集和排序順序規(guī)范。對于 Unicode 數(shù)據(jù)(nchar 和 nvarchar 列),排序只指定了排序順序。
只有在鏈接服務器使用的字符集(非 Unicode 數(shù)據(jù))、排序順序、字符串比較語法和本地服務器一致時,SQL Server 2000 才將字符串比較操作委派給提供程序。
在鏈接服務器是 SQL Server 時,SQL Server 自動確定排序的兼容性。對于其他提供程序,系統(tǒng)管理員必須為 SQL Server 指出給定的鏈接服務器上的字符數(shù)據(jù)的排序方式。在 SQL Server 2000 中,支持名為 Collation Name 的新的鏈接服務器選項。如果系統(tǒng)管理員確定鏈接服務器上采用的排序語法和 SQL Server 標準語法一致,就能將 Collation Name 選項設置為排序名。Collation Name 選項能夠使用系統(tǒng)存儲過程 sp_serveroption 來設置。只有滿足了如下兩個條件時才應該設置該選項: 遠程排序順序和字符集與指定的 SQL Server 排序一致。
OLE DB 提供程序使用的字符串比較的語法符合 SQL-92 標準規(guī)范或等同于 SQL Server 的比較語法。
為了向下兼容,仍支持 SQL Server 7.0 中的 Collation Compatible 選項。將其設置為 true 等于將 Collation Name 選項設置為 SQL Server 主數(shù)據(jù)庫的默認排序方式。新的應用程序應使用 Collation Name 選項,而不是 Collation Compatible 選項。
索引訪問
SQL Server 使用提供程序列出的索引來執(zhí)行分布式查詢的某些謂詞。該方案只能在用戶設置提供程序選項 Index as Access Path 時才能用于索引提供程序。下面是在使用索引執(zhí)行查詢時 SQL Server 在提供程序上運行的主要高級步驟: 通過使用完整的表名和索引名調用 IOpenRowset::OpenRowset 來打開索引行集。完整表名和索引名依據(jù)前面的遠程查詢方案中所述的方式生成。
通過使用完整表名調用 IOpenRowset::OpenRowset 來打開基本表行集。
通過調用 IRowsetIndex::SetRange 根據(jù)查詢謂詞設置索引行集的范圍。
通過索引行集上的 IRowset 掃描索引行集的行。
使用檢索到的索引行中的書簽列來通過 IRowsetLocate::GetRowsByBookmark 從基本表行集中獲取相應的行。
在基本表上打開行集時,行集屬性 DBPROP_IRowsetLocate 和 DBPROP_BOOKMARKS 是必需的。
單純表掃描
SQL Server 掃描提供程序的整個遠程表并在本地運行所有的查詢命令。通過調用 IOpenRowset::OpenRowset 打開表中相應的行集。SQL Server 使用目錄、架構和對象名部分按以下方式來構造提供給 OPENROWSET 的表名: 每一個名稱段都使用提供程序的引用字符 (DBLITERAL_QUOTE) 引用,然后使用 DBLITERAL_CATALOG_SEPARATOR 字符連接它們。
行集對象打開后,SQL Server 使用 IColumnsInfo 接口來驗證該表運行時元數(shù)據(jù)是否和編譯時的元數(shù)據(jù)一致。
SQL Server 使用 IRowset 接口瀏覽并使用表中的行。使用 IRowset::GetNextRows 獲取行,使用 IRowset::RestartPosition 來重定位行集的起始點,使用 IRowset::ReleaseRows 釋放行。
UPDATE 和 DELETE 語句
要從 SQL Server 分布式查詢中對遠程表進行更新和刪除,必須滿足如下條件: 提供程序必須支持在被更新或刪除的表上使用 IOpenRowset 打開的行集的書簽。
提供程序必須支持在被更新或刪除的表上使用 IOpenRowset 打開的行集合上的 IRowsetLocate 和 IRowsetChange 接口。
IRowsetChange 接口必須支持更新 (SetData) 和刪除 (DeleteRows) 方法。
如果提供程序不支持 ITransactionLocal,則僅在該提供程序設置了 Non-transacted 選項且語句不在用戶事務中時,才允許使用 UPDATE/DELETE 語句。
如果提供程序不支持 ITransactionJoin,只有不在用戶事務中時才允許 UPDATE/DELETE 語句。
下列行集屬性是在被更新的表中打開的行集所必需的:DBPROP_IRowsetLocate、DBPROP_IRowsetChange 和 DBPROP_BOOKMARKS。將DBPROP_UPDATABILITY 行集屬性設置為 DBPROPVAL_UP_CHANGE 還是 DBPROPVAL_UP_DELETE 取決于執(zhí)行的操作是 UPDATE 還是 DELETE。
以下是在提供程序上運行 UPDATE 或 DELETE 操作的高級步驟: SQL Server 通過 IOpenRowset 接口打開基本表行集。SQL Server 需要行集上的上述屬性。
SQL Server 確定符合條件的將被更新或刪除的行。
SQL Server 通過 IRowsetLocate 接口使用書簽在符合條件的行中進行定位。
使用 IRowsetChange::SetData(用于 UPDATE 操作)或 IRowsetChange::DeleteRows(用于 DELETE 操作)在符合條件的行上作出所需的更改。
INSERT 語句
支持遠程表上的 INSERT 語句的條件要比 UPDATE 和 DELETE 語句寬松: 提供程序必須支持在目的基本表中的行集上的 IRowsetChange::InsertRow 操作。
如果提供程序不支持 ITransactionLocal,則僅在鏈接服務器設置了 Non-transacted updates 選項且語句不在用戶事務中時,才允許使用 INSERT 語句。
如果提供程序不支持 ITransactionJoin,只有不在用戶事務中時才允許 INSERT 語句。
SQL Server 使用 IOpenRowset::OpenRowset 打開基本表的行集并調用 IRowsetChange::InsertRow 將新的行插入基本行集中。
傳遞查詢
除了賦予 ICommand 的命令文本是用戶提交的(不由 SQL Server 解釋)命令字符串外,本方案和“遠程查詢”方案類似。SQL Server 在調用 ICommandText::SetCommandText 時使用 DBGUID_DEFAULT 作為文字標識符。DBGUID_DEFAULT 指出提供程序應使用它的默認語法。如果該命令文本返回多個結果集(例如,如果該命令調用一個返回多個結果集的存儲過程),SQL Server 將只使用命令返回的第一個結果集。
有關 SQL Server 使用的所有 OLE DB 接口的列表,請參閱附錄 A:SQL Server 采用的 OLE DB 接口。
總結
Microsoft SQL Server 2000 為訪問異類數(shù)據(jù)源中的數(shù)據(jù)提供了最可靠的一套工具。通過了解 SQL Server 提供的 OLE-DB 接口,開發(fā)人員能夠更好地控制和完善分布式查詢。
附錄 A:SQL Server 采用的 OLE DB 接口
下表(表 4)列出了 SQL Server 使用的全部 OLE DB 接口。“必要”列說明該接口是 SQL Server 所需的 OLE DB 功能中最基本的部分,還是可選的。如果一個給定的接口未標記為必要,SQL Server 仍然能夠訪問提供程序,但是某些特殊的 SQL Server 功能或優(yōu)化功能不能用于該提供程序。
對于可選接口,“方案”列指定了使用該接口的方案(是六個方案中的一個或多個)。例如,基本表行集上的 IRowsetChange 接口是可選接口;該接口用于 UPDATE 和 DELETE 語句方案以及 INSERT 語句方案中。如果該接口不被支持,則對提供程序的 UPDATE、DELETE 和 INSERT 語句也不能被支持。其他一些可選接口的“方案”列中標記為“性能”,表示該接口能夠提高性能。例如,如果不支持 IDBSchemaRowset 接口,SQL Server 必須打開行集兩次:一次獲得元數(shù)據(jù),另一次執(zhí)行查詢。通過支持 IDBSchemaRowset,將提高 SQL Server 的性能。
表 4:SQL Server 采用的接口
對象 接口 必要 注釋 方案
Data Source 對象 IDBInitialize 是 初始化并設置數(shù)據(jù)和安全上下文。
IDBCreateSession 是 創(chuàng)建 DB 會話對象。
IDBProperties 是 獲得有關提供程序功能的信息,設置初始化屬性,必要屬性:DBPROP_INIT_TIMEOUT。
IDBInfo 否 獲得引用文字、目錄、名稱、部分、分隔符、字符等等。 遠程查詢。
DB Session 對象 IDBSchemaRowset 否 獲得表/列的元數(shù)據(jù)。
需要的行集:
TABLES、COLUMNS、PROVIDER_TYPES;
其他可能用到的行集:INDEXES、TABLE_STATISTICS。 性能,索引訪問。
IOpenRowset 是 打開表、索引和柱狀圖上的行集。
IGetDataSource 是 用于從 DB 會話對象返回到 DSO。
IDBCreateCommand 否 用于為支持查詢的提供程序創(chuàng)建命令對象(查詢)。 遠程查詢,傳遞查詢。
ITransactionLocal 否 用于事務方式的更新。 UPDATE、DELETE 和 INSERT 語句。
ITransactionJoin 否 用于分布式事務支持。 如果在用戶事務中,則必需有 UPDATE、DELETE 和 INSERT 語句。
Rowset 對象 IRowset 是 掃描行。
IAccessor 是 綁定到行集中的列。
IColumnsInfo 是 獲得行集中的列信息。
IRowsetInfo 是 獲得行集屬性的信息。
IRowsetLocate 否 UPDATE/DELETE 操作和基于索引的查找所需;用于使用書簽來查找行。 索引訪問,UPDATE 和 DELETE 語句。
IRowsetChange 否 對行集進行 INSERTS/UPDATES/
DELETES 操作所需的?;诨颈淼男屑瘧С衷摻涌诘?INSERT、UPDATE 和
DELETE 語句。 UPDATE、DELETE 和 INSERT 語句。
IConvertType 是 用于驗證該行集是否支持它的列上的數(shù)據(jù)類型轉換。
Index IRowset 是 掃描行。 索引訪問,性能。
IAccessor 是 綁定到行集中的列。 索引訪問,性能。
IColumnsInfo 是 獲得行集中的列信息。 索引訪問,性能。
IRowsetInfo 是 獲得行集屬性的信息。 索引訪問,性能。
IRowsetIndex 是 只用于索引上的行集合;用于索引功能(設置范圍、搜索)。 索引訪問,性能。
Command ICommand 是   遠程查詢,傳遞查詢。
ICommandText 是 用于定義查詢文本。 遠程查詢,傳遞查詢。
IColumnsInfo 是 用于獲得查詢結果需要的列元數(shù)據(jù)。 遠程查詢,傳遞查詢。
ICommandProperties 是 用于指定根據(jù)命令返回的行集合上所需的屬性。 遠程查詢,傳遞查詢。
ICommandWithParameters 否 用于帶參數(shù)查詢命令。 遠程查詢,性能。
ICommandPrepare 否 用于準備獲取元數(shù)據(jù)的命令(如果可用,用于傳遞查詢中)。 遠程查詢,性能。
Error 對象 IErrorRecords 是 用于獲得指向 IErrorInfo 接口的對應于個別錯誤記錄的指針。
IErrorInfo 是 用于獲得指向 IErrorInfo 接口的對應于個別錯誤記錄的指針。
任意對象 ISupportErrorInfo 否 用于驗證給定的接口是否支持錯誤對象。
注意:   Index 對象、Command 對象和 Error 對象不是強制的。如果它們被支持,則在“必要”列中指定的接口是強制的。
附錄 B: 用于生成遠程查詢的 SQL 子集
SQL Server 查詢處理器根據(jù) SQL 命令提供程序生成的 SQL 子集取決于提供程序依據(jù) DBPROP_SQLSUPPORT 屬性所支持的語法級別。
支持 SQL Entry 級別和 ODBC Core 的 SQL 命令提供程序
SQL Server 將下面的 SQL 語言的子集用于由 SQL 命令提供程序執(zhí)行的查詢,這些 SQL 命令提供程序必須支持 SQL-92 Entry 級別或 ODBC Core : 包含 SELECT、FROM、WHERE、GROUP BY、UNION、UNION ALL、ORDER BY DESC、ASC 和 HAVING 子句的 SELECT 語句。
UNION 和 UNION ALL 只能在支持 SQL-92 Entry 級別的提供程序上生成,不能在支持 ODBC Core 的提供程序上生成。
SELECT 子句: 在 SELECT 列表中的分級子查詢。
不帶 AS 關鍵字的列別名。
FROM 子句: 沒有使用顯式 JOIN 關鍵字;使用逗號分隔的表名指定內(nèi)部聯(lián)接,在遠程查詢中沒有指定外部聯(lián)接。
嵌套查詢的格式:FROM ( <嵌套查詢> ) <別名>。
不帶 AS 關鍵字的表別名。
WHERE 子句使用帶有 [NOT] EXISTS、ANY 和 ALL 的子查詢。
表達式: 聚合函數(shù):MIN([DISTINCT])、MAX([DISTINCT])、COUNT([DISTINCT])、SUM([DISTINCT])、AVG([DISTINCT]) 和 COUNT(*)。
比較運算符:<、=、<=、>、<>、>=、IS NULL 和 IS NOT NULL。
布爾運算符:AND、OR 和 NOT。
數(shù)學運算符:+、-、* 和 /。
常數(shù): 數(shù)字和貨幣常數(shù)總是由 () 括住。
字符常數(shù)使用 ‘‘ 引住。
支持 SQL Minimum 級別的 SQL 命令提供程序
對于支持 SQL Minimum 級別的 SQL 命令提供程序,SQL Server 生成如下語法的 SQL。
此處的語法來自 ODBC 3.0 中描述的 SQL Minimum 語法。所有與該語法的不同之處都被突出顯示。以粗斜體顯示的項目就是添加到 ODBC 3.0 所述的 SQL Minimum 語法中的項目。以綠色刪去的項目是從該語法中刪除的項目。
select-statement ::=SELECT [ALL | DISTINCT] select-listFROM table-reference-list[WHERE search-condition][order-by-clause]SELECT clauseselect-list ::= * | select-sublist [, select-sublist]...select-sublist ::= expression [alias]alias ::= user-defined-nameFROM clausetable-reference-list ::= table-referencetable-identifier ::= user-defined-nametable-name ::= table-identifiertable-reference ::= table-nameWHERE clausesearch-condition ::= boolean-term [OR search-condition]boolean-term ::= boolean-factor [AND boolean-term]boolean-factor ::= [NOT] boolean-primaryboolean-primary ::= comparison-predicate | ( search-condition )comparison-predicate ::= expression comparison-operator expression| expression IS [NOT] NULLcomparison-operator ::= < | > | <= | >= | = | <>ORDER BY clauseorder-by-clause ::= ORDER BY sort-specification [, sort-specification]...sort-specification ::= { | column-name } [ASC | DESC]Common syntactic elementsexpression ::= term | expression {+|–} termterm ::= factor | term {*|/} factorfactor ::= [+|–] primaryprimary ::= column-name| literal| ( expression )column-name ::= [table-name.]column-identifierliteral ::= character-string-literal| integer-literal| exact-numeric-literalcharacter-string-literal ::= ‘{character}?(字符指驅動程序或數(shù)據(jù)源的字符集中的任意字符。要在字符串中包括引號字符 (‘),請使用兩個引號字符 (‘‘)。)integer-literal ::= [+ | -] unsigned-integerexact-numeric-literal::= [+ | -] unsigned-integer [period unsigned-integer]| period unsigned-integerbase-table-name ::= base-table-identifierbase-table-identifier ::= user-defined-namecolumn-identifier ::= user-defined-nameuser-defined-name ::= letter[digit | letter | _]...unsigned-integer ::= {digit}?digit ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9period ::= .
本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
SQL Server 2008數(shù)據(jù)庫實用教程-第12章
SQL Server備份語句
Hibernate入門
第11章 數(shù)據(jù)庫應用
SQL Server:使用一個語句塊插入多條記錄
查詢SQL Server更改記錄的語句
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服