作者:
Bogdan Crivat,微軟公司
時間: 2005年3月
適用于:
微軟 SQL Server 2005
SQL Server 數據挖掘(SQL Server Data Mining)
摘要: 介紹SQL Server 2005數據挖掘的新API以及幾種常用的開發場景。
版權
在這篇文章中所包含的信息代表了從發布日起微軟對所討論的問題的當前觀點。因為微軟必須對市場的變換做出響應,它不應該被理解為微軟所必須承擔的任務的一部分,微軟也不能保證在發布日之后所提出的信息的精確性。
這個白皮書僅僅是為了信息的目的,微軟對本文中的信息不做任何授權、表示、暗含或規定。
依從所有可適用的版權法是用戶的責任。沒有限制權利在版權之下,這個文檔的部分不允許被再生產,存放或介紹入檢索系統, 或被以任何形式傳送或通過任何手段(電子, 機械, 影印, 記錄, 或其他) 或為任何目的,沒有微軟的明確書面允許。
微軟對于在這篇文章中所包含的主題擁有專利、專利申請、商標、版權或其他的一些知識產權。除了微軟明確提供的一些書面的特許契約,這個文檔的并不提供給您任何專利、商標、版權或其他知識產權的執照。
版權所有2005 Microsoft Corporation。
Microsoft 和Visual Studio在美國或其他國家都有注冊商標或微軟的商標。
在這里的實際的公司和產品的名字可能是他們各自的商標。
隨著微軟SQL Server 2005的誕生,統計技術和機器學習算法的綜合產物,也就是眾所周知的數據挖掘,被帶入了一個新的階段。在SQL Server 2005中,數據挖掘最重要的轉變是改變了它的目標用戶。除了作為一個科學的實驗工具,面向有限的專業人士,如今SQL Server 數據挖掘已廣泛存在,成為開發者捶手可得的工具,并且已經做好了在更廣闊的領域中應用的準備。從電子數據表格到網絡游戲,從點到點通訊系統到應用服務器,絕大多數應用都有這樣一個共同點:它們不得不進行數據處理。在進行數據處理的時候,它們使用特定的標準API來訪問數據。在SQL Server 2005數據挖掘的數據處理系統中,這些API也同樣可以被智能的嵌入到應用中。
這篇文章帶你思考將SQL Server數據挖掘嵌入到應用中的契機。文章重點關注可編程內容,即通過寫代碼來使用數據挖掘技術和增強服務器特性。我們將給出一系列可以被數據挖掘引擎執行的常用任務,并針對它們展示微軟SQL Server數據挖掘體系結構的解決方案。之后,我們將列舉一些客戶端產品(Adomd.NET 和 OLE DB)的可編程API。之后的一個章節專注于Analysis Management Objects所管理的API。隨后,我們將展示服務器創建新的存儲過程以及添加新的算法插件和查看器等擴展功能.
數據挖掘應用也可以結合聯機分析處理(OLAP)、Reporting Services或者Integration Services來創建。然而,這篇文章不介紹這些內容,而是嚴格通過代碼來介紹數據挖掘功能和如何增強數據挖掘功能。
數據挖掘和聯機分析處理都是微軟分析服務的組件。本篇文章中介紹的客戶端API同時適用于這兩種組件。但是,本文的介紹僅針對數據挖掘。其中的場景、代碼實例、元數據對象都是針對數據挖掘的。
與 Microsoft Analysis Services 2005 通訊
讓我們從Microsoft Analysis Services 2005(與數據挖掘服務器之間)的通訊協議開始。客戶端通過Analysis Services 2005來執行這個通訊協議(比如使用Microsoft OLE DB Provider for Analysis Services 9.0 或者 Adomd.NET),并且這個協議也必須被其它客戶端執行。
Microsoft Analysis Services 2005 使用SOAP作為最外層的通訊層。(更多關于SOAP的內容請訪問這個網頁。)SOAP為應用程序定義了一系列可以通過XML消息來調用的方法。 這些方法由Microsoft Analysis Services 發布,使用XML for Analysis或者 XMLA來定義。
XMLA規范是由一個超過20家研究商業智能的龍頭企業(包括微軟公司、Hyperion和SAS 學會)組成的組織提出的,它是一個標準的OLAP和數據挖掘技術接口。 更多關于XMLA的信息,請點擊這里。
XMLA定義了兩種發送給服務器的請求,以及服務器進行響應返回的信息的格式。請求的類型是“發現(Discover)”和“執行(Execute)”。“發現”用來從服務器獲取信息和元數據。例如, “發現”可以用來獲取服務器上一系列挖掘模型以及它們的屬性(列描述、算法等等)。“執行”用來執行對服務器的命令,如創建一個新的目錄或者挖掘模型、訓練一個模型、或者執行一個查詢。
數據定義語言( DDL) 和 數據挖掘擴展語言(DMX)
XMLA的“執行”命令可應用于多種任務。這里有幾個例子:
· 創建(Create)命令:這些命令在服務器上創建一個新的元數據對象,它們包含被創建的對象的全部或部分屬性,例如名稱、數據綁定、挖掘模型和挖掘結構中的列、挖掘模型的數據挖掘算法等等。
· 修改(Alter)命令:這些命令修改已存在的服務器元數據對象的屬性。
· 刪除(Drop)命令:這些命令用來從服務器上去掉元數據對象。
· 處理(Process)命令:這些命令用來初始化那些基于當前綁定的訓練數據集定義的元數據對象上的訓練序列。
· 語句 (查詢語句)。
當一個XMLA“執行”請求描述一個對象(如創建Create或者修改Alter語句)或者將一個對象定義為一個動作的目標(如處理Process或刪除Drop)時,命令的內容由Microsoft Analysis Services 數據定義語言(Data Definition Language —— DDL)組成。DDL是Analysis Services 2005中元數據以及元數據操作的內部表示方法。 服務器上的對象存儲在DDL中,商業智能化項目由若干DDL片段組成。關于DDL的更多細節,請查看SQL Server 2005 在線文檔中的“分析服務腳本語言(Analysis Services scripting language)”。
另一方面,在數據挖掘任務中,當XMLA請求是一個語句的時候,XMLA “執行”請求使用一種查詢語言——DMX(數據挖掘擴展Data Mining eXtensions語言)作為它的請求的內容。DMX語言在針對數據挖掘的OLE DB 規范中定義,在這里可以使用。
Microsoft Analysis Service 2005 也可以使用另一種查詢語言來執行語句——MDX。MDX語言是為OLAP組件所設計的。所以,這里我們只關注DMX。
區分DDL和DMX是非常重要的:DDL是一種由Analysis Services 2005使用的類XML語言,用來描述、管理和指定元數據。DDL可以很方便的擴展到XMLA。
而DMX是一種為數據挖掘而設計出的類SQL語言。DMX與SQL非常類似,DMX包含這樣的結構,它們允許創建和操作元數據對象(想想SQL中的CREATE TABLE 或者INSERT INTO語句,DMX中有與其等價的CREATE MINING MODEL 和INSERT INTO 語句)。然而,對于管理元數據對象的任務來說,DMX的靈活性比DDL要差。DMX語句無法擴展到XMLA;但是它們可以被固定的XMLA結構所包括。
文章結尾處的附錄1提供更多Microsoft Analysis Services 2005協議部署的細節內容。
SOAP相對來說比較容易操作;大多數開發工具都提供針對創建、傳輸、接收SOAP包的幫助。但是,選擇使用DDL請求還是DMX請求,并把它按照適當的格式封裝到XMLA語句中就不是一件那么容易的事情了。所以開發者需要比僅僅使用XML流作為通訊方法更好的工具。這也就是為什么如今可編程API存在的原因。這些API將XMLA請求的相關操作作業打包,分析XMLA的響應信息,并且向開發者提供一個更具邏輯性的通訊視圖,用來操作內部細節。也有一小部分API可以被Microsoft SQL Server 數據挖掘應用。選擇哪個API取決于客戶端執行的請求的類型和客戶端的開發環境。
下一節將分析典型的數據挖掘在客戶端/服務器端通訊(C/S)時的客戶端請求。之后的章節將從各種數據挖掘可編程API處理典型請求時的方法以及它們支持的客戶端環境的角度,具體展示這些API以及它們之間的差別。
數據挖掘任務
SQL Server數據挖掘服務器支持多種請求。對于每一種請求,我們將給出可用的DDL命令和等價的DMX:
· 元數據的發現:這些請求允許客戶端應用根據一些屬性,如挖掘模型的列、使用的算法、被訓練的數據集,迭代服務器上已存在的元數據對象,并且從中選擇一個或多個有用的元數據。XMLA規范為這類請求定義了發現(Discover)命令,沒有與其直接對應的DMX或DDL。
· 元數據的定義:這些請求是一系列對服務器上的數據結構的定義。這些數據結構是挖掘結構和挖掘模型,它們由目錄(數據庫)組合在一起。針對這些請求的XMLA命令是執行(Execute),包括DDL用來創建和修改的Create 或 Alter 語句。也可以使用DMX的 CREATE語句,盡管它的靈活性要比DDL 的Create語句差。
· 模型的訓練:這些請求為服務器端的數據挖掘模型執行訓練處理。訓練可以使用預先綁定的數據(在元數據定義時決定),也可以只描述當前正在處理的操作的數據集。XMLA命令還是 執行(Execute),包含一個DDL的處理(Process)語句。在DMX中,訓練可以由插入(INSERT INTO)命令得到。
· 查詢模型:這些請求包括(但不局限于)在數據挖掘中我們常說的記分(Scoring)和預測(Predicting)。 我們將查詢定義為使用數據挖掘所建立的模型的過程。這些請求由發送到服務器端的DMX語句組成。
· 訂閱進度通知:這些請求非常方便地顯示一個進度條,這個進度條用來顯示在執行一個很長的操作時或者在指定時間檢查服務器狀態時的實際進展情況。這類請求不能使用DMX創建。它們擁有跟蹤的功能,作為帶DDL訂閱(Subscribe)語句的XMLA執行(Execute)命令來進行傳輸。
對這些任務有了基本概念后,我們可以正式開始列舉可編程API及它們的特性了。上述任務中的最后一項,關于進度的通知,我們將單立一節的內容進行講解,下面的API章節就不再討論這個任務了。
通用API
我們將探討兩種常用的API:Adomd.NET和OLE DB。它們的差別在于它們的目標環境不同: OLEDB (OLE for Databases)主要針對非托管應用(盡管它也可以被用于托管應用);而Adomd.NET針對托管應用。下邊我們將看到,這些API具有非常相似的結構。它們都基于非常有名的數據庫訪問范例。
Adomd.NET 作為通用API
Adomd.NET是由Microsoft Analysis Services 2000提供的舊ADOMD庫的托管版本。這個庫專門為Microsoft Analysis Services 2005的客戶端而設計。它執行ADO.NET數據訪問范例(包括一系列標準接口,如 IDbConnection、IDbCommand、 IDataReader 等等),并且使用Microsoft Analysis Services 2005提供的許多特性來擴展這些范例。
在.NET框架中, System.Data 命名空間使你可以建立從多個數據源有效管理數據的組件。關于此點的更多內容請參考關于 System.Data 命名空間的MSDN文檔。 System.Data 擁有多種特性,它定義一系列可以被.NET數據提供程序執行的用來訪問關系型數據庫的接口。微軟分析服務(Microsoft Analysis Services)是一個多維數據庫,它比普通關系型數據庫擁有更強大的功能。Adomd.NET是一個.NET數據提供程序,能執行提供給.NET數據提供程序的一系列標準 System.Data 接口,這些接口的功能在Analysis Services 2005中得以增強,也增加了很多在關系型數據庫中不使用的新特性。
Adomd.NET作為SQL Server 2005連接組件的一部份被安裝,也可以單獨下載進行安裝。在從應用程序使用它之前,必須在機器上安裝Adomd.NET數據提供程序。
這一節的代碼示例使用Visual Studio 2005的C# 2.0實現。經過一個簡單的“翻譯”過程,它們也可以被Visual Studio 套件的任意托管語言(如Visual Basic .NET或Visual C++ .NET)運轉。
在應用程序中使用 Adomd.NET時,必須先添加一個 Microsoft.AnalysisServices.AdomdClient. dll程序集,使用類似如下的代碼進行添加:
using Microsoft.AnalysisServices.AdomdClient;
下一步,連接Microsoft Analysis Services 2005 服務器:
AdomdConnectionconn = new AdomdConnection();
conn.ConnectionString = "Data Source=localhost; " +
"Initial Catalog=MyCatalog";
conn.Open();
在數據挖掘任務列表中,第一個是元數據對象的發現。就像我們前邊所說的一樣,元數據的發現由XMLA發現(Discover)命令實現。Adomd.NET提供兩種簡單的方法來發現元數據。第一種與AMO非常相似:
foreach (MiningModel model in conn.MiningModels)
{
Console.WriteLine(model.Name);
}
微軟分析服務開發團隊盡了很大的努力來確認常用的計劃都已包含于Adomd.NET Connection類所發布的程序集中。你可以使用之前的這些代碼來訪問數據庫中的挖掘結構集、一個結構中或者整個數據庫中的挖掘模型列表、以及模型和結構中的列。Adomd.NET 擁有遠超過AMO 的功能,它允許代碼這樣構成分級模型:
foreach (MiningContentNode node in model.Content)
{
foreach( MiningContentNode in node.Children )
{
// 使用節點的屬性
}
}
對Microsoft Analysis Services 2005中的OLAP計劃來說,Adomd.NET Connection 對象所發布的程序集比數據挖掘所提供的程序集更加適用。所以在Adomd.NET中你可以使用相同的方法來瀏覽立方體和維度。
發現服務器元數據的第二種方法與OLE DB的方法非常相似,也就是執行一個發現(Discovery)命令來傳輸一個GUID計劃和一系列約束,然后返回一個可以被遍歷的表型結果。 有些計劃返回的是分級表型結果(嵌套表)。這也就是為什么在Adomd.NET 中,一個發現操作的返回值是一個 數據集 (DataSet ) ;對比ADO.NET ,它返回的是一個數據表。數據集可以描述表之間的關系,所以數據集可以包含一些發現操作的嵌套表型結果。下邊的一段代碼片段發現了一個挖掘模型的內容,并且使用數據集得到了響應NODE_DISTRIBUTION嵌套表計劃的嵌套行:
Guid modelContent = new Guid("{3ADD8A76-D8B9-11D2-8D2A-00E029154FDE}");
object[] arRestrictions = new object[3];
// 約束發現(Discovery)MyCatalog目錄中DecisionTree1模型的內容。
// 第二個約束(MODEL_SCHEMA) 在這里忽略。
arRestrictions[0] = "MyCatalog";
arRestrictions[1] = null;
arRestrictions[2] = "DecisionTree1";
DataSet dsContent = conn.GetSchemaDataSet(
modelContent, arRestrictions);
// 一致性檢查:確認關系值為1
Debug.Assert( dsContent.Relations.Count == 1);
DataRelation relation = dsContent.Relations[0];
DataTable topTable = relation.ParentTable;
foreach (DataRow row in topTable.Rows)
{
// 使用最上層表中的列
Console.WriteLine("NODE_CAPTION=" + row["NODE_CAPTION"]);
Console.WriteLine("NODE_UNIQUE_NAME" + row["NODE_UNIQUE_NAME"]);
// 根據關系描述,取得嵌套行
DataRow[]distRows = row.GetChildRows(relation);
foreach (DataRow distRow in distRows)
{
// 使用嵌套表中的列
Console.WriteLine(distRow["ATTRIBUTE_VALUE"]);
}
}
與OLE DB非常相似,Adomd.NET提供發送請求到服務器的命令。這些請求可以是DDL或者DMX的;所以它們可以創建或者修改已經存在的、用來訓練挖掘結構和挖掘模型的元數據對象(DDL和DMX),也可以查詢已存在的模型(只支持DMX)。我們也就可以通過此點來區分元數據的創建、處理,和DMX的查詢。它們的區別在于:DMX查詢返回一個表型結果(分層的或者單層的),而元數據創建和處理語句只返回一個成功或者失敗。Adomd.NET公開了一些執行(Execute)方法,其中兩種對于返回成功/失敗的請求和返回表格型數據的請求非常有用。
第一種:我們使用一個DDL處理語句作為示例,任何其它的DDL語句(如Alter、Create或者Drop)也可以使用相同的代碼。
AdomdCommand cmd = new AdomdCommand();
cmd.Connection = conn;
cmd.CommandText = "
"xmlns=\"http://schemas.microsoft.com/analysisservices/2003/engine\">"+"<Type>ProcessDefault</Type>" +
" <Object>" +
" <DatabaseID>MyCatalog</DatabaseID>" +
" <MiningStructureID>Structure1</MiningStructureID>" +
" </Object>" +
"</Process>";
cmd.ExecuteNonQuery();
同樣, ExecuteNonQuery 也可以執行一個DMX語句來產生相同的結果:
"INSERT INTO MINING STRUCTURE Structure1"
當 ExecuteNonQuery 被調用的時候,如果請求執行成功了,語句將返回;如果執行失敗將報一個異常。在之后的例子中,將給出異常的具體信息,如服務器返回的錯誤信息。
第二種執行方法是 ExecuteReader 。這種方法應該在語句的返回值肯定是表型的時候被調用。就像我們前邊所提到的一樣,Microsoft Analysis Services 2005返回的結果有時會是分層表型結果。例如,讓我們考慮這樣的一個模型, Model1,它根據消費者的年齡、他/她汽車的顏色來預測消費者的性別和購買商品的清單。當然,這樣的模型可能并沒有現實意義,但是,它卻是一個很容易使DMX語句返回分層表結構結果的例子。
下面的代碼使用 AdomdCommand 來傳輸一個預測查詢給服務器,并讀取最上層返回值(預測的性別)和嵌套返回值(預測的商品列表):
cmd.CommandText = "SELECT Gender, Products FROM Model2 " +
"NATURAL PREDICTION JOIN "+
"( SELECT 30 AS Age, 'Black' as CarColor) AS T";
AdomdDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
// 使用上層結果,預測性別
Console.WriteLine( rdr.GetString(0) );
// 為第一列的嵌套內容獲得一個nested reader
AdomdDataReader nestedReader = rdr.GetDataReader(1);
// 讀嵌套內容并使用嵌套數據
while (nestedReader.Read())
{
Console.WriteLine(nestedReader.GetString(0));
}
nestedReader.Close();
}
調用 GetDataReader 將返回一個新的實例 AdomdDatareader 類,它被初始化后用來訪問對列編號了的嵌套表。如果指定的列并不是一個被嵌套的表,“執行”方法將返回一個異常。我們可以使用類似如下代碼的語言來判斷Datareader中的列是不是一個嵌套表:
if (rdr.GetFieldType(1) == typeof(AdomdDataReader) )
{
// 如果進入If循環,rdr的第一列是一個嵌套表
}
在現實生活中,最有可能根據用戶的實際輸入來進行預測。一個常見的Web應用場景是這樣的,用戶給出年齡和汽車的顏色,應用程序代碼產生一個DMX請求來預測該客戶購買商品的清單。當開發者對DMX和相關的數據類型有一個很好的理解的時候,查詢可以使用將客戶錄入的所有字符串連接起來的方式進行創建。 然而,這樣的方法具有潛在的威脅,它可能引起DMX嵌入錯誤或研發錯誤。一種更好的方式是使用參數來建立查詢,將用戶輸入的內容作為參數的值。Adomd.NET對DMX的參數化查詢提供了大量的支持,就像下面的例子一樣。這段代碼不包括讀取返回值的內容,因為它與之前的代碼片段是一樣的。
cmd.CommandText = "SELECT Gender, Products FROM Model2 " +
"NATURAL PREDICTION JOIN "+
"( SELECT @Age AS Age, @Color as CarColor) AS T";
AdomdParameter paramAge, paramColor;
paramAge = cmd.CreateParameter();
paramAge.Direction = ParameterDirection.Input;
paramAge.ParameterName = "Age";
cmd.Parameters.Add(paramAge);
paramColor = cmd.CreateParameter();
paramColor.Direction = ParameterDirection.Input;
paramColor.ParameterName = "Color";
cmd.Parameters.Add(paramColor);
cmd.Parameters["Age"].Value = 30; // 用戶在這里輸入
cmd.Parameters["Color"].Value = "Black"; // 用戶在這里輸入
AdomdDataReader rdr = cmd.ExecuteReader();
請注意,參數不一定非是數值。請考慮這樣的DMX語句:
INSERT INTO MyModel(Col1, Col2)
OPENQUERY(DataSource, "SELECT ColA, ColB FROM Table") AS T
或者是:
SELECT PREDICT(Products, 5) FROM MyModel NATURAL PREDICTION JOIN
OPENQUERY(DataSource, "SELECT ColA, ColB FROM Table") AS T
這兩個語句都用了一個OPENQUERY 函數來描述執行時被服務器使用的表型內容(訓練挖據模型,分別進行預測)。使用Adomd.NET,我們可以使用一個參數來取代OPENQUERY函數,并且向服務器傳輸一些表型內容。查詢可能是這樣的:
INSERT INTO MyModel(Col1, Col2)
@MyTabularContent AS T
或者是:
SELECT PREDICT(Products, 5) FROM MyModel NATURAL PREDICTION JOIN
@MyTabularContent AS T
在這些例子中, 參數 MyTabularContent 可以是一個 數據表(DataTable ) 或者執行一個 IDataReader .NET接口。相比來說,數據表更容易使用, IDataReader 接口具有不需要將所有數據保存在內存中的優勢。 IDataReader 執行的一個例子是客戶端應用執行的SQL查詢所返回的 SqlDatareader 。當然,一個SQL查詢請求也可以在OPENQUERY 功能中被提交,但是這種請求的前提是服務器已經訪問到了SQL數據庫。表型參數為兩種情況所設計:
· 數據庫中的數據是客戶端可見但是服務器端不可見的(這種情況應該使用 IDataReader )
· 數據在客戶端應用程序所占用的內存中( DataTable 可以在這種情況時使用)
Adomd.NET 一個獨有的特點是可以使用XML返回選定的列。Microsoft Analysis Services 2005為指定的查詢返回這樣的列。例如:
SELECT * FROM MyModel.PMML
這個語句將返回PMML 2.1格式下MyModel 模型的內容(即被支持PMML的MyModel使用的數據挖掘算法)。除了例如模型名稱、PMML緩沖區大小這類元信息外,這個語句的返回值還包括指定的列和包含PMML的MODEL_PMML(一種被數據挖掘團隊設計出來的XML格式,用來描述挖掘模型的內容)。
這個XML的內容可以以字符串方式被訪問,但是Adomd.NET擁有分析XML列的能力(基于服務器端發來的指定的列類型來判斷) 并且將它們發布為一個 System.Xml.XmlReader 對象。這些列也可以作為字符串被讀取。以下的示例代碼使用這一特性來訪問帶XML目錄的列,同時使用字符串和 XmlReader 兩種方法。
cmd.CommandText = "SELECT * from [MyModel].PMML";
AdomdDataReader rdr = cmd.ExecuteReader();
// 遍歷響應結果,讀取第5列,MODEL_PMML
while (rdr.Read())
{
// 取得列值
object objXMLValue = rdr.GetValue(5);
if (objXMLValue is System.Xml.XmlReader)
{
//使用一個XML reader
System.Xml.XmlReader pmmlReader =
(System.Xml.XmlReader)objXMLValue;
//在這里讀PMML
}
// 使用字符串來獲取這列
string strPMMLAsString = rdr.GetString(5);
}
Adomd.NET 的另一個特性是連續訪問服務器響應,將在 進度通知:使用跟蹤對象 一節中具體闡述。
Adomd.NET是Microsoft Analysis Services 2005中最具靈活性,最容易使用的客戶端API。在編寫以微軟分析服務為目標的.NET應用操作時也同樣推薦使用它。它提供了類AMO訪問服務器元數據的大量特性,它允許執行DDL和DMX語句,并且它對DMX語句的參數也有很好的支持。
OLE DB作為通用API
在微軟Windows操作系統中,OLE DB是進行數據訪問最常用的API。OLE DB是針對OLE對象的規范。這些OLE對象有一系列標準接口。這些接口的標準化使得一個編程模型幾乎可以訪問所有類型的數據源。微軟SQL Server數據挖掘有一個OLE DB提供程序。這個提供程序能將OLE DB編程模型翻譯成數據挖掘所需要的內容。
關于 OLE DB的更多內容,請訪問MSDN OLE DB頁。
OLE DB可以被很多種編程語言直接使用。在本機(非托管)C++中,可以創建OLE DB對象,并且可以直接調用OLE DB的方法。ALT使用者模版(ALT Consumer Templates)也為OLE DB使用者應用程序提供了一系列有用的類。在Visual Basic或者VBA中,OLE DB提供程序可以在ADO(ActiveX Data Objects,ActiveX數據對象)中使用。在托管語言中,我們可以使用ADO.NET 庫來調用OLE DB提供程序。
OLEDB編程模型以如下對象為中心。首先,數據源必須由服務器端初始化和控制。其次,在這個數據源上必須初始化一個通訊對話。OLE DB架構的第三個重要組成部分就是命令,它們將服務器請求打包。每個服務器請求都是對話的一部分。OLE DB架構的第四個組成部分是服務器響應。大多數數據挖掘任務可以被OLE DB命令所執行。例如,可以使用一個命令來傳輸DMX語句,也可以傳輸一個DDL語句來創建一個新的元數據。但是命令并不能傳輸一個發現元數據語句(Discovery)。所以針對此點,OLE DB定義了一個可以被對話執行的 IDBSchemaRowset 接口。這里我們需要注意的是,ADO和ADO.NET有一個封裝了數據源和OLE DB對話的連接對象(Connection)。這兩種標準的OLE DE對象(數據源和OLE DB對話)公開的功能在ADO和ADO.NET的連接對象中可用。
所有的OLE DB對象(數據源、對話、命令和響應)經常在COM組件中執行來調用OLE提供程序。
下面的圖1給出了一個OLE DB解決方案的框架:
如圖中所示,首先,各個客戶端上安裝的OLE DB提供程序使用OLE DB來連接服務器。Microsoft Analysis Services 2005的OLE DB提供程序是在安裝SQL Server 2005的連接組件時安裝的。
OLEDB連接經常通過連接字符串的方法來初始化。連接字符串包含一系列有分號分隔開的“名字-值”字符對,即屬性。這些屬性描述了OLE DB連接初始化時的各個參數。所有的OLE DB包(如ATL使用者模版、ADO、或者ADO.NET)都根據連接字符串來進行初始化。這里給出一個用來連接Microsoft Analysis Services 2005的OLE DB連接字符串的例子:
"Provider=MSOLAP; Data Source=localhost; "
第一個屬性 Provider 描述示例中指定的提供程序。
"MSOLAP" 是微軟分析服務中OLE DB提供程序的名字。請注意這個名字是依賴版本的。如果一臺機器上安裝了多個分析服務OLE DB提供程序(如一個來自Analysis Services 2005,一個來自Analysis Services 2000),就需要使用更加準確的名字來區分版本:Analysis Services 2000使用“MSOLAP.2”,Analysis Services 2005使用“MSOLAP.3”。第二個屬性“Data Source”表示要連接的數據源。它一般都是一個機器名,但是也可以是其它表達方式。例如,它可以是一個文件名,或者是一個網絡URL,如我們將在下文“HTTP Pump”章所見到的一樣。關于分析服務OLE DB提供程序屬性的更多信息,你可以從SQL Server在線信息中得到。
下面這段代碼是一個VBA應用程序中使用OLE DB的例子,它使用了ADO。具有相似功能的C#代碼(使用ADO.NET)和非托管C++代碼在附錄2中。
為使用ADO,需要為你的Visual Basic (或者VBA)工程添加一個指向Microsoft ActiveX Data Object庫(你機器中最新版本的庫)的引用。以下的代碼片段是在2.8版本上進行測試的:
1 Dim Conn As ADODB.Connection
2
3 Set Conn = New ADODB.Connection
4 Conn.Open ("Provider=MSOLAP.3; Data Source=localhost;" _
5 & "Initial Catalog=MyCatalog")
在第一行和第三行創建并初始化了一個ADODB連接對象。在第四行,就像我們前邊所說的,ADO連接對象封裝了兩種OLE DB對象:數據源和對話。在連接字符串中,你將看到一個之前沒有討論過的屬性:“Initial Catalog”。它定義服務器上將被這個連接使用的數據庫。讓我們使用這個連接對象來完成我們之前列舉的數據挖掘任務。
對于元數據發現(Discovery),ADO連接提供了一個 OpenSchema 函數(在OLE DB對話中打包了 IDBSchemaRowset 接口)。
OpenSchema 包含3個參數:
· 枚舉,用來描述將要被發現的計劃。
· 約束集,將被應用于發現操作的一系列約束。
· 全局唯一標識符(GUID),描述提供程序指定的計劃。
我們嘗試在MyCatalog 數據庫上發現服務器端的挖掘模型。這不是數據挖掘模型計劃(指定的提供程序計劃)中預先計劃好的枚舉,所以第一個參數就是 adSchemaProviderSpecific 。第二個參數,約束集,包含用來查找模型(“MyCatalog”)的目錄名。第三個參數包含Analysis Services OLE DB提供程序中,能識別挖掘模型計劃的GUID的字符表。
6 Const DMSCHEMA_MINING_MODELS="{3add8a77-d8b9-11d2-8d2a-00e029154fde}"
7 Dim Restrictions()
8 Restrictions = Array("MyCatalog")
9 Dim rsSchema As ADODB.Recordset
10 Set rsSchema = Conn.OpenSchema(
adSchemaProviderSpecific,
Restrictions,
DMSCHEMA_MINING_MODELS)
數據挖掘的OLE DB規范包含分析服務的OLE DB提供程序支持的計劃的完整定義,包括發現(Discovery)語句返回的列和約束。
OpenSchema 返回一個 ADODB.Recordset 對象。 Recordset 對象封裝了一個表型服務器響應。下面我們將看到如何遍歷這個對象以及如何從中提取信息。這段代碼的目的是枚舉挖掘模型的名字。 像我們所知道的一樣,在數據挖掘OLE DB里,挖掘模型計劃中的每一行對應一種挖掘模型,并且包含一個“MODEL_NAME”列,列中存儲挖掘模型的名字。
下面一段代碼顯示如何從 Recordset 對象中查找指定的列,以及如何從這些列中提取信息。
11 ' 從(MODEL_NAME)中查找列
12 Dim iModelNameColumn As Integer
13 For iModelNameColumn = 0 To rsSchema.Fields.Count - 1
14 If rsSchema.Fields(iModelNameColumn).Name = "MODEL_NAME" Then
15 GoTo Found
16 End If
17 Next
18 Error (1)
19 Found:
20 ' 讀取Recordset的返回值
21 rsSchema.MoveFirst
22 While Not rsSchema.EOF
23 Debug.Print rsSchema.Fields(iModelNameColumn).Value
24 rsSchema.MoveNext
25 Wend
如你所看到的一樣,這段代碼先遍歷了 Recordset 對象的所有字段。每個字段表示響應的一列。我們根據這些字段的索引MODEL_NAME進行查找。如果找到了這樣的一列,就開始遍歷它的行內容,否則就報錯。
為了遍歷行, Recordset 指針先移到數據的開始位置。之后一行一行的讀取行數據。對于每一行都讀取和使用MODEL_NAME字段的值。
一些數據挖掘任務(如創建新元數據對象或訓練已存在的對象)可以通過發送DDL語句到服務器來執行。讓我們看看DDL語句是如何被OLE DB通過ADO來傳輸的。我們將使用與之前一樣的連接對象,并介紹一個新的OLE DB對象的ADO包, ADODB.Command 對象:
26 Dim Cmd As ADODB.Command
27 Set Cmd = New ADODB.Command
28 Cmd.ActiveConnection = Conn
29
30 Dim strProcessDDLStmt As String
31 strProcessDDLStmt = "" _
32 & "</Process
xmlns=""http://schemas.microsoft.com/analysisservices/2003/engine"">" _
33 & " <Type>ProcessStructure</Type>" _
34 & " <Object>" _
35 & " <DatabaseID>CheckInTestDB</DatabaseID>" _
36 & " </Object>Structure1" _
37 & " </Process>" _
38 & ""
39
40 Cmd.CommandText = strProcessDDLStmt
41 Cmd.Execute
42
命令在一個活躍連接中執行。這個活躍的連接就是第28行中的內容。一般來說,這個命令包含著執行語句。這在 CommandText 屬性(第40行)中設置。當ADO為Analysis Services 2005打包OLE DB提供程序時, CommandText 屬性支持DMX語句和DDL語句(就像之前所展示的一樣)。命令的執行被“執行(Execute)”方法初始化(第41行)。執行經常返回一個 ADODB.Recordset 對象(可用于之前的發現(Discovery)代碼段的表型服務器響應)。但是,處理操作是沒有服務器響應的,它不返回成功或失敗。如果出現了一個錯誤,ADO將報一個異常并停止正在運行的代碼。因此,如果執行到了第42行,就說明執行成功了。
在之前的代碼中,可以將 CommandText 屬性改為一個DDL語句,比如 Alter 、 Create 或者 Dro p ;或改為一個DMX語句,如CREATE MINING MODEL或者INSERT INTO,它可以實現絕大多數挖掘任務。唯一一個需要附加補充的是查詢挖掘模型。DMX查詢與一般的無響應信息語句不同,因為:
· 它返回一個表型結果。
· 表型結果可能包含多級的表(嵌套表)。
· DMX 支持參數。
我們可以從返回單級表的DMX查詢開始看起,使用我們最開始使用的對象來對比(命令和連接):
43 Cmd.ActiveConnection = Conn
44 Cmd.CommandText = "SELECT NODE_CAPTION FROM DecisionTree1.CONTENT" _
45 &"where NODE_TYPE=2"
46
47 Dim rs As ADODB.Recordset
48 Set rs = Cmd.Execute()
49 rs.MoveFirst
50 While Not rs.EOF
51 Debug.Print rs.Fields(0).Value
52 Wend
53 rs.Close
如我們之前所提到的一樣,DMX語句由 CommandText 屬性來傳輸。與發現(Discovery)使用相同的方式來遍歷 Recordset 。第44行用到的查詢只返回一列,這里并不真正需要從recordset 字段來查找列;相反的,它應該由它的索引得到(第51行)第0字段的內容。也請注意第53行中對 Recordset 的配置。當 Recordset 是活躍的時候,命令對象不能執行之后的語句。
OLE DB規范也允許返回更加復雜的結果集,如表型列或者嵌套表。下面給出一個服務器響應是嵌套表的例子,我們將使用DMX語句來添加查詢更復雜的第二列NODE_DISTRIBUTION。所以新的查詢如下所示:
"SELECT NODE_CAPTION, NODE_DISTRIBUTION FROM DecisionTree1.CONTENT WHERE NODE_TYPE=2"
NODE_DISTRIBUTION 是一個典型的嵌套表例子。根據數據挖掘的OLE DB規范,模型中的NODE_DISTRIBUTION列包含當前行所在節點的屬性值的分布。例如,在一棵預測頭發顏色的決策樹中,對每一個樹節點,這一列都描述有多少實例是黑發,多少實例是金發,多少實例是灰發。
執行命令在新的一列中并不改變。實際上唯一需要改變的就是 Recordset 的遍歷代碼,需要進行適合表的新列的改變。在代碼中可以很容易的從 Recordset 作為字段值的屬性返回一列的值。如果實例中的列是一個嵌套表,列值將產生一個新的 Recordset ,再遍歷整個嵌套表。
所以,在51行以下應該執行如下的代碼:
52 Debug.Assert( rs.Fields(1).Type = adChapter)
53 Dim nestedRS As ADODB.Recordset
54 Set nestedRS = rs.Fields(1)
55 nestedRS.MoveFirst
56 While Not nestedRS.EOF
57 Debug.Print nestedRS.Fields(0).Value
58 Wend
59 nestedRS.Close
第52行語句用來在將值寫入嵌套 Recordset 前,確認列的類型是正確的。這行語句也可以用來判斷制定的列是不是一個嵌套表。
應為擁有遍歷嵌套表的能力,此時數據挖掘查詢產生的任何返回值都可以在你的應用中被使用了。
DMX也支持查詢中的參數。參數可以取代DMX查詢中的任何值。例如,可以使用一個參數來代替上述查詢語句中 where 子句里的NODE_TYPE 的值“2”。在數據挖掘應用中,也有少數參數非常有用的場景,比如生成一個單獨的查詢(關于單獨查詢的詳細內容,請看“Adomd.NET”一節)。
想在DMX查詢中將一個值變為一個參數,我們使用參數指示標志 @ 來開始替換,使用“ @ 唯一的參數名”。這樣VBA代碼片段中的第45行就可以變成:
45 &"where NODE_TYPE=@typeParam"
然后,在執行命令之前,我們應該插入這樣的一段代碼來確保能正確的使用新的參數。請注意,盡管實際數據可能與參數的值很不同,但是使用參數并不會改變服務器響應的格式。所以上述遍歷 Recordset 的代碼可以并不改變。
46 Cmd.NamedParameters = True
47
48 Dim typeParameter As ADODB.Parameter
49 Set typeParameter = Cmd.CreateParameter()
50 typeParameter.Direction = adParamInput
51 typeParameter.Name = "typeParam"
52 typeParameter.Value = 2
53 typeParameter.Type = adInteger
54 typeParameter.Size = 4
55
56 Cmd.Parameters.Append typeParameter
在分析服務的OLE DB提供程序中使用參數時,如下的幾步非常重要:
· 命令必須使NamedParameters可用(第46行)。分析服務的OLE DB提供程序只支持命名了的參數。
· 參數的名字必須符合查詢中的相應參數,但是在這里不使用 @ 前綴(第51行)。
· 可以只傳輸參數(第50行)。
· 參數的類型和大小必須聲明(第53和54行)。
想對數據挖掘的OLE DB規則進行很好的理解,需要充分使用Microsoft Analysis Services 2005數據挖掘的特性。一旦設計好了數據挖掘查詢,OLE DB就成為了一個可以執行它們、可以管理數據挖掘服務器的完整且具有通用性的API。關于在非托管C++或ADO.NET中C#使用OLEDB 的代碼,請看本文附錄2中的代碼片段。
Analysis Management Objects – AMO
如同名字所顯示的一樣,AMO是一個用來管理任務的API。它非常適用于描述元數據屬性的細節信息。AMO是一種非常符合微軟分析服務的數據定義語言(DDL)的對象模型,在AMO中描述元數據對象。它允許迭代元數據對象、創建新對象、修改已存在對象。在AMO對象模型中,用DDL描述的每個屬性都可以被檢查和修改。AMO也可以用來檢查和修改服務器屬性,包括注冊/非注冊型插件算法,或者可注冊/不可注冊數據挖掘算法。AMO在元數據的定義和發現,以及服務器對象的訓練上都非常有用。但是,它并不支持執行查詢語句。
在討論細節信息之前,我們應該先來說明一下AMO是一個托管庫。所以,它可以在由通用執行時間組件(CLR——Common Language Runtime)兼容的編程語言開發的應用程序中使用,如C#、托管執行的C++、或者Visual Basic .NET。要想使用AMO, 我們需要在客戶機上安裝SQL Server 2005連接組件。
在使用AMO的時候,我們首先應該在應用程序的開始處引用 Microsoft.AnalysisServices.dll 庫。之后,AMO對象模型就可以使用了。先來連接服務器:
Microsoft.AnalysisServices.Server server = new Server();
Server.Connect("localhost");
一旦連接成功,服務器端的元數據對象就可以被分級檢查到:
Databases dbCollection = server.Databases;
foreach( Database db in dbCollection )
{
MiningStructures structCollection = db.MiningStructures;
foreach( MiningStructure struct in structCollection)
{
Console.WriteLine( struct.Name );
}
}
如果想修改已存在的元數據對象,我們只需要修改它的屬性。使用如下代碼:
model.Algorithm="Microsoft_Decision_Trees".
then call "Update".
model.Update();
當Update被調用時,你所做的修改就將被提交到服務器,同時刷新本地的信息集。
在服務器上添加一個新的元數據、在各自的集合上創建新成員這兩個方法,與修改功能也是非常相似的:
MiningStructure myStructure;
MiningModel myModel = myStructure.Models.Add();
之后填充對象的內容:
myModel.Name = "New Model"
myModel.Algorithm = "Microsoft_Clustering"
然后通過調用 Update() 來提交對服務器端所作的修改:
myModel.Update();
當操作未能成功執行完畢時,更新操作(Update)將返回一個異常。通常產生異常的情況是:
· 被更新的屬性不完整或者不一致。
· 由于當前用戶未能擁有足夠的權限而引起的服務器不能更新對象。
當出現異常的時候,我們可以找到問題的所在并修復它。
AMO在處理Analysis Services 2005服務器端元數據上具有很強的功能,但是它并不支持之前所提到的數據挖掘任務中的部分任務。它不提供進度通知的功能,也不提供查詢挖掘模型的功能(一般情況下,它不支持DMX語句的執行)。如果你的應用需要瀏覽和檢查Analysis Services 2005服務器,使用AMO是最好的選擇。但是,如果除此以外你還需要執行語句或者顯示進度通知,AMO的功能就不夠了。下一章將為大家介紹兩種通用API,它們支持分析服務所公開的所有特性。
進度通知:使用跟蹤對象
當在服務器端同時執行多個事件時,微軟分析服務就會發送一系列通知。這些事件包括用戶的登入登出、 執行請求的開始位置和結束位置、不同服務器對象正在執行的進度情況。在接收到通知以后,管理員就可以檢查服務器在每一刻的狀態。正在處理服務器對象的用戶也可以從中了解正在執行的操作是什么,以及還需要執行多長時間。
這一節中,我們將討論應用程序是如何從Microsoft Analysis Services 2005服務器來接收進度通知的。我們從如何發現服務器發出的通知看起。 之后,我們簡短的介紹應用程序如何訂閱它所感興趣的服務器通知。最后,我們給出一個需要處理進度通知的應用程序的編程模型。
在進行深入的討論之前,我們先來明確一下,SQL Server 2005使用一個客戶端分析器(Profiler)來處理這些通知。使用這個分析器,用戶可以真正根據自己的需要進行通知的選擇,然后檢查這些通知的具體內容。分析器應用程序也允許記錄服務器通知,可以為了以后檢查通知內容而先將它們保存下來。它也可以使用性能計數器(Performance Counter)將正在執行的不同的性能指示器的相關服務器通知整合起來。大多數應用程序并不需要在代碼中執行服務器通知,這一節針對那些需要使用數據挖掘客戶端高級用戶接口的開發者來進行講解。
服務器發出的每種通知都是一個表型行。這一行包含一些基本信息,例如通知的種類、時間戳、服務器進程ID、以及服務器的名稱。其它列分別對應特定的事件,例如處理通知的Progress Total、起始時間、結束時間、在服務器上已經執行的時間。服務器發出的所有通知被存放在一張虛擬表中,它為每個事件保留一行,以及被任何服務器事件支持的所有列的集合。這意味著:如果列A只被一個指定事件支持,它將在這張虛擬表中所有的事件行中出現,但是不支持A的事件的列A字段是空值。說這張表是一張虛擬表,是因為它并不存放在內存中,也不能被直接訪問到。當沒有人去看服務器事件進展情況的時候,它被存放在一個只有管理員可以訪問到的“flight-recorder”文件中,用來提供過去出現錯誤的原因相關的有價值的信息。
這張虛擬表中的列集可以用常規XMLA發現語句(Discovery)來發現。這個計劃的XMLA名稱是DISCOVER_TRACE_COLUMNS,它的GUID是{a07ccd18-8148-11d0-87bb-00c04fc33942}。這個計劃中的每一行描述事件表中的一列,計劃至少有一列,使用事件的XML格式進行描述。XML格式的描述如下所示:
<COLUMN>
<ID>0</ID>
<TYPE>1</TYPE>
<NAME>EventClass</NAME>
<DESCRIPTION>Event Class is used to categorize events.</DESCRIPTION>
<FILTERABLE>false</FILTERABLE>
<REPEATABLE>false</REPEATABLE>
<REPEATEDBASE>false</REPEATEDBASE>
</COLUMN>
就這本白皮書來說,我們所感興趣的屬性有 ID 、 名字( Name )和描述( Description )。
ID 是列的數值型標志符。像我們關于事件的討論一樣,一個事件通過定義ID來指定列。列的名字和描述對于客戶端來說非常重要。基于這些屬性,客戶端應用程序可以判斷哪些列是自己所感興趣的列,哪些列是可以忽略的。 ID 為 0 的列是“服務器通知”這張虛擬表中最重要的列,因為它是用來定義事件類型的。Microsoft Analysis Services 2005發布的所有通知都包含此列。
發現服務器發布的事件是一個與發現列很相似的任務。使用的XMLA計劃是 DISCOVER_TRACE_EVENT_CATEGORIES,它的GUID是 {a07ccd19-8148-11d0-87bb-00c04fc33942}。這個任務中的每一行描述一個服務器發布的事件類別,任務記錄事件類別中的全部事件。當使用XML形式定義事件類別時,任務中的代碼如下所示:
<EVENTCATEGORY>
<NAME>Queries Events</NAME>
<TYPE>0</TYPE>
<DESCRITION>Collection of events for queries.</DESCRITION>
<EVENTLIST>
<EVENT>
<ID>9</ID>
<NAME>Query Begin</NAME>
<DESCRIPTION>Query begin.</DESCRIPTION>
<EVENTCOLUMNLIST>
<EVENTCOLUMN>
<ID>0</ID>
</EVENTCOLUMN>
<EVENTCOLUMN>
<ID>2<ID>
</EVENTCOLUMN>
...
</EVENTCOLUMNLIST>
</EVENT>
<EVENT>
<ID>10</ID>
<NAME>Query End</NAME>
<DESCRIPTION>Query end.</DESCRIPTION>
<EVENTCOLUMNLIST>
<EVENTCOLUMN>
<ID>0</ID>
</EVENTCOLUMN>
<EVENTCOLUMN>
<ID>2</ID>
</EVENTCOLUMN>
...
</EVENTCOLUMNLIST>
</EVENT>
....
</EVENTLIST>
</EVENTCATEGORY>
所以,一個事件類別可以包含多個帶不同ID的事件。如之前所說的一樣,每個事件擁有它們自己的列,并且它們都包含提供事件類信息的列0。
另一個特殊的列是列1,事件子類(event subclass)。它被多個事件共享。事件子類這一列允許跟蹤用戶,例如,我們可以用它來區一個 ProgressStart 事件到底是來自于數據挖掘,還是OLAP維度處理。如果一個事件中出現了列1,這一列要比其它列的定義復雜一些。如下文所示:
<EVENTCOLUMN>
<ID>1</ID>
<EVENTCOLUMNSUBCLASSLIST>
<EVENTCOLUMNSUBCLASS>
<ID>1</ID>
<NAME>Process</NAME>
</EVENTCOLUMNSUBCLASS>
<EVENTCOLUMNSUBCLASS>
<ID>2</ID>
<NAME>Merge</NAME>
</EVENTCOLUMNSUBCLASS>
...
</EVENTCOLUMNSUBCLASSLIST>
</EVENTCOLUMN>
這個更加復雜的定義描述了當前事件中列1可能出現的所有值的含義。
當一個應用程序決定了它感興趣的事件或者事件列是哪些的時候,它可以訂閱這些信息作為服務器通知。這個訂閱功能在服務器創建跟蹤對象的時候被創建。跟蹤對象的功能與包含服務器通知的虛擬表的視圖的功能相似。除此功能以外,跟蹤對象存有服務器對象的所有屬性。它可以被創建、修改、刪除以及根據許可情況進行約束。一個跟蹤聲明會指定它感興趣的事件(類似于關系型視圖中的WHERE子句)以及事件將返回哪些列。定義跟蹤的DDL可以包含更多的過濾條件,如“只返回那些列C是特定值的返回值”,但是這些過濾條件并不是本文要討論的內容。這些高級選項可以從SQL Server 2005 在線文檔中進行了解,在文檔中有專門一節“跟蹤要素(分析服務腳本語言)”。
讓我們來考慮這樣的一個應用程序,它用來訓練挖掘模型,而且只訂閱了如下進度報告事件:
· Progress Report Begin (事件ID是5)
· Progress Report Current (事件ID是7)
· Progress Report End (事件ID是6)
· Progress Report Error(事件ID是8)
對每一個事件來說,感興趣的列是:
· 列 0, EventClass 。
· 列9, ProgressTotal ,完成當前任務所需要執行的步驟數(此列僅在Progress Report Current事件可用)。
· 列10, IntegerData ,數據挖掘進度通知中的屬性,存儲正在執行的任務的當前步驟(此列僅在Progress Report Current事件可用)。
· 列42, TextData ,包含當前步驟的詳細描述。
我們使用下面的DDL語句創建這個跟蹤:
<Create
xmlns="http://schemas.microsoft.com/analysisservices/2003/engine">
<ObjectDefinition>
<Trace>
<ID>DemoTrace</ID>
<Name>DemoTrace</Name>
<Events>
<Event>
<EventID>5</EventID>
<Columns>
<ColumnID>0</ColumnID>
<ColumnID>42</ColumnID>
</Columns>
</Event>
<Event>
<Event ID>6</Event ID>
<Columns>
<ColumnID>0</ColumnID>
<ColumnID>42</ColumnID>
</Columns>
</Event>
<Event>
<EventID>7</EventID>
<Columns>
<ColumnID>0</ColumnID>
<ColumnID>9</ColumnID>
<ColumnID>10</ColumnID>
<ColumnID>42</ColumnID>
</Columns>
</Event>
<Event>
<EventID>8</EventID>
<Columns>
<Columns>0</Columns>
<Columns>42</Columns>
</Columns>
</Event>
</Events>
</Trace>
</ObjectDefinition>
</Create>
一旦跟蹤被創建,客戶端應用程序就將訂閱這個跟蹤。訂閱跟蹤的功能與執行返回表型
時間: 2005年3月
適用于:
微軟 SQL Server 2005
SQL Server 數據挖掘(SQL Server Data Mining)
摘要: 介紹SQL Server 2005數據挖掘的新API以及幾種常用的開發場景。
版權
在這篇文章中所包含的信息代表了從發布日起微軟對所討論的問題的當前觀點。因為微軟必須對市場的變換做出響應,它不應該被理解為微軟所必須承擔的任務的一部分,微軟也不能保證在發布日之后所提出的信息的精確性。
這個白皮書僅僅是為了信息的目的,微軟對本文中的信息不做任何授權、表示、暗含或規定。
依從所有可適用的版權法是用戶的責任。沒有限制權利在版權之下,這個文檔的部分不允許被再生產,存放或介紹入檢索系統, 或被以任何形式傳送或通過任何手段(電子, 機械, 影印, 記錄, 或其他) 或為任何目的,沒有微軟的明確書面允許。
微軟對于在這篇文章中所包含的主題擁有專利、專利申請、商標、版權或其他的一些知識產權。除了微軟明確提供的一些書面的特許契約,這個文檔的并不提供給您任何專利、商標、版權或其他知識產權的執照。
版權所有2005 Microsoft Corporation。
Microsoft 和Visual Studio在美國或其他國家都有注冊商標或微軟的商標。
在這里的實際的公司和產品的名字可能是他們各自的商標。
QUOTE:
目錄
概述
與 Microsoft Analysis Services 2005通訊
數據定義語言(DDL) 和 數據挖掘擴展語言(DMX)
數據挖掘任務
通用API
Adomd.NET 作為通用API
OLE DB作為通用API
Analysis Management Objects – AMO
進度通知:使用跟蹤對象
無服務器的數據挖掘:本地挖掘模型
擴展SQL Server 數據挖掘功能
使用Adomd.NET Server 擴展DMX
插件算法和內容查看器
應用場景建議
應用場景1:簡單的數據挖掘預測
應用場景2:Web應用——使用服務器上現有模型的規則
應用場景3:為當前數據在服務器上創建和訓練一個新的模型
小結
附錄 1:Microsoft Analysis Services 2005服務器上的常用操作以及請求的協議格式
附錄 2:在Ado.NET 和 C++中使用 OLE DB
非托管 C++
ADO.NET
概述
概述
與 Microsoft Analysis Services 2005通訊
數據定義語言(DDL) 和 數據挖掘擴展語言(DMX)
數據挖掘任務
通用API
Adomd.NET 作為通用API
OLE DB作為通用API
Analysis Management Objects – AMO
進度通知:使用跟蹤對象
無服務器的數據挖掘:本地挖掘模型
擴展SQL Server 數據挖掘功能
使用Adomd.NET Server 擴展DMX
插件算法和內容查看器
應用場景建議
應用場景1:簡單的數據挖掘預測
應用場景2:Web應用——使用服務器上現有模型的規則
應用場景3:為當前數據在服務器上創建和訓練一個新的模型
小結
附錄 1:Microsoft Analysis Services 2005服務器上的常用操作以及請求的協議格式
附錄 2:在Ado.NET 和 C++中使用 OLE DB
非托管 C++
ADO.NET
隨著微軟SQL Server 2005的誕生,統計技術和機器學習算法的綜合產物,也就是眾所周知的數據挖掘,被帶入了一個新的階段。在SQL Server 2005中,數據挖掘最重要的轉變是改變了它的目標用戶。除了作為一個科學的實驗工具,面向有限的專業人士,如今SQL Server 數據挖掘已廣泛存在,成為開發者捶手可得的工具,并且已經做好了在更廣闊的領域中應用的準備。從電子數據表格到網絡游戲,從點到點通訊系統到應用服務器,絕大多數應用都有這樣一個共同點:它們不得不進行數據處理。在進行數據處理的時候,它們使用特定的標準API來訪問數據。在SQL Server 2005數據挖掘的數據處理系統中,這些API也同樣可以被智能的嵌入到應用中。
這篇文章帶你思考將SQL Server數據挖掘嵌入到應用中的契機。文章重點關注可編程內容,即通過寫代碼來使用數據挖掘技術和增強服務器特性。我們將給出一系列可以被數據挖掘引擎執行的常用任務,并針對它們展示微軟SQL Server數據挖掘體系結構的解決方案。之后,我們將列舉一些客戶端產品(Adomd.NET 和 OLE DB)的可編程API。之后的一個章節專注于Analysis Management Objects所管理的API。隨后,我們將展示服務器創建新的存儲過程以及添加新的算法插件和查看器等擴展功能.
數據挖掘應用也可以結合聯機分析處理(OLAP)、Reporting Services或者Integration Services來創建。然而,這篇文章不介紹這些內容,而是嚴格通過代碼來介紹數據挖掘功能和如何增強數據挖掘功能。
數據挖掘和聯機分析處理都是微軟分析服務的組件。本篇文章中介紹的客戶端API同時適用于這兩種組件。但是,本文的介紹僅針對數據挖掘。其中的場景、代碼實例、元數據對象都是針對數據挖掘的。
與 Microsoft Analysis Services 2005 通訊
讓我們從Microsoft Analysis Services 2005(與數據挖掘服務器之間)的通訊協議開始。客戶端通過Analysis Services 2005來執行這個通訊協議(比如使用Microsoft OLE DB Provider for Analysis Services 9.0 或者 Adomd.NET),并且這個協議也必須被其它客戶端執行。
Microsoft Analysis Services 2005 使用SOAP作為最外層的通訊層。(更多關于SOAP的內容請訪問這個網頁。)SOAP為應用程序定義了一系列可以通過XML消息來調用的方法。 這些方法由Microsoft Analysis Services 發布,使用XML for Analysis或者 XMLA來定義。
XMLA規范是由一個超過20家研究商業智能的龍頭企業(包括微軟公司、Hyperion和SAS 學會)組成的組織提出的,它是一個標準的OLAP和數據挖掘技術接口。 更多關于XMLA的信息,請點擊這里。
XMLA定義了兩種發送給服務器的請求,以及服務器進行響應返回的信息的格式。請求的類型是“發現(Discover)”和“執行(Execute)”。“發現”用來從服務器獲取信息和元數據。例如, “發現”可以用來獲取服務器上一系列挖掘模型以及它們的屬性(列描述、算法等等)。“執行”用來執行對服務器的命令,如創建一個新的目錄或者挖掘模型、訓練一個模型、或者執行一個查詢。
數據定義語言( DDL) 和 數據挖掘擴展語言(DMX)
XMLA的“執行”命令可應用于多種任務。這里有幾個例子:
· 創建(Create)命令:這些命令在服務器上創建一個新的元數據對象,它們包含被創建的對象的全部或部分屬性,例如名稱、數據綁定、挖掘模型和挖掘結構中的列、挖掘模型的數據挖掘算法等等。
· 修改(Alter)命令:這些命令修改已存在的服務器元數據對象的屬性。
· 刪除(Drop)命令:這些命令用來從服務器上去掉元數據對象。
· 處理(Process)命令:這些命令用來初始化那些基于當前綁定的訓練數據集定義的元數據對象上的訓練序列。
· 語句 (查詢語句)。
當一個XMLA“執行”請求描述一個對象(如創建Create或者修改Alter語句)或者將一個對象定義為一個動作的目標(如處理Process或刪除Drop)時,命令的內容由Microsoft Analysis Services 數據定義語言(Data Definition Language —— DDL)組成。DDL是Analysis Services 2005中元數據以及元數據操作的內部表示方法。 服務器上的對象存儲在DDL中,商業智能化項目由若干DDL片段組成。關于DDL的更多細節,請查看SQL Server 2005 在線文檔中的“分析服務腳本語言(Analysis Services scripting language)”。
另一方面,在數據挖掘任務中,當XMLA請求是一個語句的時候,XMLA “執行”請求使用一種查詢語言——DMX(數據挖掘擴展Data Mining eXtensions語言)作為它的請求的內容。DMX語言在針對數據挖掘的OLE DB 規范中定義,在這里可以使用。
Microsoft Analysis Service 2005 也可以使用另一種查詢語言來執行語句——MDX。MDX語言是為OLAP組件所設計的。所以,這里我們只關注DMX。
區分DDL和DMX是非常重要的:DDL是一種由Analysis Services 2005使用的類XML語言,用來描述、管理和指定元數據。DDL可以很方便的擴展到XMLA。
而DMX是一種為數據挖掘而設計出的類SQL語言。DMX與SQL非常類似,DMX包含這樣的結構,它們允許創建和操作元數據對象(想想SQL中的CREATE TABLE 或者INSERT INTO語句,DMX中有與其等價的CREATE MINING MODEL 和INSERT INTO 語句)。然而,對于管理元數據對象的任務來說,DMX的靈活性比DDL要差。DMX語句無法擴展到XMLA;但是它們可以被固定的XMLA結構所包括。
文章結尾處的附錄1提供更多Microsoft Analysis Services 2005協議部署的細節內容。
SOAP相對來說比較容易操作;大多數開發工具都提供針對創建、傳輸、接收SOAP包的幫助。但是,選擇使用DDL請求還是DMX請求,并把它按照適當的格式封裝到XMLA語句中就不是一件那么容易的事情了。所以開發者需要比僅僅使用XML流作為通訊方法更好的工具。這也就是為什么如今可編程API存在的原因。這些API將XMLA請求的相關操作作業打包,分析XMLA的響應信息,并且向開發者提供一個更具邏輯性的通訊視圖,用來操作內部細節。也有一小部分API可以被Microsoft SQL Server 數據挖掘應用。選擇哪個API取決于客戶端執行的請求的類型和客戶端的開發環境。
下一節將分析典型的數據挖掘在客戶端/服務器端通訊(C/S)時的客戶端請求。之后的章節將從各種數據挖掘可編程API處理典型請求時的方法以及它們支持的客戶端環境的角度,具體展示這些API以及它們之間的差別。
數據挖掘任務
SQL Server數據挖掘服務器支持多種請求。對于每一種請求,我們將給出可用的DDL命令和等價的DMX:
· 元數據的發現:這些請求允許客戶端應用根據一些屬性,如挖掘模型的列、使用的算法、被訓練的數據集,迭代服務器上已存在的元數據對象,并且從中選擇一個或多個有用的元數據。XMLA規范為這類請求定義了發現(Discover)命令,沒有與其直接對應的DMX或DDL。
· 元數據的定義:這些請求是一系列對服務器上的數據結構的定義。這些數據結構是挖掘結構和挖掘模型,它們由目錄(數據庫)組合在一起。針對這些請求的XMLA命令是執行(Execute),包括DDL用來創建和修改的Create 或 Alter 語句。也可以使用DMX的 CREATE語句,盡管它的靈活性要比DDL 的Create語句差。
· 模型的訓練:這些請求為服務器端的數據挖掘模型執行訓練處理。訓練可以使用預先綁定的數據(在元數據定義時決定),也可以只描述當前正在處理的操作的數據集。XMLA命令還是 執行(Execute),包含一個DDL的處理(Process)語句。在DMX中,訓練可以由插入(INSERT INTO)命令得到。
· 查詢模型:這些請求包括(但不局限于)在數據挖掘中我們常說的記分(Scoring)和預測(Predicting)。 我們將查詢定義為使用數據挖掘所建立的模型的過程。這些請求由發送到服務器端的DMX語句組成。
· 訂閱進度通知:這些請求非常方便地顯示一個進度條,這個進度條用來顯示在執行一個很長的操作時或者在指定時間檢查服務器狀態時的實際進展情況。這類請求不能使用DMX創建。它們擁有跟蹤的功能,作為帶DDL訂閱(Subscribe)語句的XMLA執行(Execute)命令來進行傳輸。
對這些任務有了基本概念后,我們可以正式開始列舉可編程API及它們的特性了。上述任務中的最后一項,關于進度的通知,我們將單立一節的內容進行講解,下面的API章節就不再討論這個任務了。
通用API
我們將探討兩種常用的API:Adomd.NET和OLE DB。它們的差別在于它們的目標環境不同: OLEDB (OLE for Databases)主要針對非托管應用(盡管它也可以被用于托管應用);而Adomd.NET針對托管應用。下邊我們將看到,這些API具有非常相似的結構。它們都基于非常有名的數據庫訪問范例。
Adomd.NET 作為通用API
Adomd.NET是由Microsoft Analysis Services 2000提供的舊ADOMD庫的托管版本。這個庫專門為Microsoft Analysis Services 2005的客戶端而設計。它執行ADO.NET數據訪問范例(包括一系列標準接口,如 IDbConnection、IDbCommand、 IDataReader 等等),并且使用Microsoft Analysis Services 2005提供的許多特性來擴展這些范例。
在.NET框架中, System.Data 命名空間使你可以建立從多個數據源有效管理數據的組件。關于此點的更多內容請參考關于 System.Data 命名空間的MSDN文檔。 System.Data 擁有多種特性,它定義一系列可以被.NET數據提供程序執行的用來訪問關系型數據庫的接口。微軟分析服務(Microsoft Analysis Services)是一個多維數據庫,它比普通關系型數據庫擁有更強大的功能。Adomd.NET是一個.NET數據提供程序,能執行提供給.NET數據提供程序的一系列標準 System.Data 接口,這些接口的功能在Analysis Services 2005中得以增強,也增加了很多在關系型數據庫中不使用的新特性。
Adomd.NET作為SQL Server 2005連接組件的一部份被安裝,也可以單獨下載進行安裝。在從應用程序使用它之前,必須在機器上安裝Adomd.NET數據提供程序。
這一節的代碼示例使用Visual Studio 2005的C# 2.0實現。經過一個簡單的“翻譯”過程,它們也可以被Visual Studio 套件的任意托管語言(如Visual Basic .NET或Visual C++ .NET)運轉。
在應用程序中使用 Adomd.NET時,必須先添加一個 Microsoft.AnalysisServices.AdomdClient. dll程序集,使用類似如下的代碼進行添加:
using Microsoft.AnalysisServices.AdomdClient;
下一步,連接Microsoft Analysis Services 2005 服務器:
AdomdConnectionconn = new AdomdConnection();
conn.ConnectionString = "Data Source=localhost; " +
"Initial Catalog=MyCatalog";
conn.Open();
在數據挖掘任務列表中,第一個是元數據對象的發現。就像我們前邊所說的一樣,元數據的發現由XMLA發現(Discover)命令實現。Adomd.NET提供兩種簡單的方法來發現元數據。第一種與AMO非常相似:
foreach (MiningModel model in conn.MiningModels)
{
Console.WriteLine(model.Name);
}
微軟分析服務開發團隊盡了很大的努力來確認常用的計劃都已包含于Adomd.NET Connection類所發布的程序集中。你可以使用之前的這些代碼來訪問數據庫中的挖掘結構集、一個結構中或者整個數據庫中的挖掘模型列表、以及模型和結構中的列。Adomd.NET 擁有遠超過AMO 的功能,它允許代碼這樣構成分級模型:
foreach (MiningContentNode node in model.Content)
{
foreach( MiningContentNode in node.Children )
{
// 使用節點的屬性
}
}
對Microsoft Analysis Services 2005中的OLAP計劃來說,Adomd.NET Connection 對象所發布的程序集比數據挖掘所提供的程序集更加適用。所以在Adomd.NET中你可以使用相同的方法來瀏覽立方體和維度。
發現服務器元數據的第二種方法與OLE DB的方法非常相似,也就是執行一個發現(Discovery)命令來傳輸一個GUID計劃和一系列約束,然后返回一個可以被遍歷的表型結果。 有些計劃返回的是分級表型結果(嵌套表)。這也就是為什么在Adomd.NET 中,一個發現操作的返回值是一個 數據集 (DataSet ) ;對比ADO.NET ,它返回的是一個數據表。數據集可以描述表之間的關系,所以數據集可以包含一些發現操作的嵌套表型結果。下邊的一段代碼片段發現了一個挖掘模型的內容,并且使用數據集得到了響應NODE_DISTRIBUTION嵌套表計劃的嵌套行:
Guid modelContent = new Guid("{3ADD8A76-D8B9-11D2-8D2A-00E029154FDE}");
object[] arRestrictions = new object[3];
// 約束發現(Discovery)MyCatalog目錄中DecisionTree1模型的內容。
// 第二個約束(MODEL_SCHEMA) 在這里忽略。
arRestrictions[0] = "MyCatalog";
arRestrictions[1] = null;
arRestrictions[2] = "DecisionTree1";
DataSet dsContent = conn.GetSchemaDataSet(
modelContent, arRestrictions);
// 一致性檢查:確認關系值為1
Debug.Assert( dsContent.Relations.Count == 1);
DataRelation relation = dsContent.Relations[0];
DataTable topTable = relation.ParentTable;
foreach (DataRow row in topTable.Rows)
{
// 使用最上層表中的列
Console.WriteLine("NODE_CAPTION=" + row["NODE_CAPTION"]);
Console.WriteLine("NODE_UNIQUE_NAME" + row["NODE_UNIQUE_NAME"]);
// 根據關系描述,取得嵌套行
DataRow[]distRows = row.GetChildRows(relation);
foreach (DataRow distRow in distRows)
{
// 使用嵌套表中的列
Console.WriteLine(distRow["ATTRIBUTE_VALUE"]);
}
}
與OLE DB非常相似,Adomd.NET提供發送請求到服務器的命令。這些請求可以是DDL或者DMX的;所以它們可以創建或者修改已經存在的、用來訓練挖掘結構和挖掘模型的元數據對象(DDL和DMX),也可以查詢已存在的模型(只支持DMX)。我們也就可以通過此點來區分元數據的創建、處理,和DMX的查詢。它們的區別在于:DMX查詢返回一個表型結果(分層的或者單層的),而元數據創建和處理語句只返回一個成功或者失敗。Adomd.NET公開了一些執行(Execute)方法,其中兩種對于返回成功/失敗的請求和返回表格型數據的請求非常有用。
第一種:我們使用一個DDL處理語句作為示例,任何其它的DDL語句(如Alter、Create或者Drop)也可以使用相同的代碼。
AdomdCommand cmd = new AdomdCommand();
cmd.Connection = conn;
cmd.CommandText = "
"xmlns=\"http://schemas.microsoft.com/analysisservices/2003/engine\">"+"<Type>ProcessDefault</Type>" +
" <Object>" +
" <DatabaseID>MyCatalog</DatabaseID>" +
" <MiningStructureID>Structure1</MiningStructureID>" +
" </Object>" +
"</Process>";
cmd.ExecuteNonQuery();
同樣, ExecuteNonQuery 也可以執行一個DMX語句來產生相同的結果:
"INSERT INTO MINING STRUCTURE Structure1"
當 ExecuteNonQuery 被調用的時候,如果請求執行成功了,語句將返回;如果執行失敗將報一個異常。在之后的例子中,將給出異常的具體信息,如服務器返回的錯誤信息。
第二種執行方法是 ExecuteReader 。這種方法應該在語句的返回值肯定是表型的時候被調用。就像我們前邊所提到的一樣,Microsoft Analysis Services 2005返回的結果有時會是分層表型結果。例如,讓我們考慮這樣的一個模型, Model1,它根據消費者的年齡、他/她汽車的顏色來預測消費者的性別和購買商品的清單。當然,這樣的模型可能并沒有現實意義,但是,它卻是一個很容易使DMX語句返回分層表結構結果的例子。
下面的代碼使用 AdomdCommand 來傳輸一個預測查詢給服務器,并讀取最上層返回值(預測的性別)和嵌套返回值(預測的商品列表):
cmd.CommandText = "SELECT Gender, Products FROM Model2 " +
"NATURAL PREDICTION JOIN "+
"( SELECT 30 AS Age, 'Black' as CarColor) AS T";
AdomdDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
// 使用上層結果,預測性別
Console.WriteLine( rdr.GetString(0) );
// 為第一列的嵌套內容獲得一個nested reader
AdomdDataReader nestedReader = rdr.GetDataReader(1);
// 讀嵌套內容并使用嵌套數據
while (nestedReader.Read())
{
Console.WriteLine(nestedReader.GetString(0));
}
nestedReader.Close();
}
調用 GetDataReader 將返回一個新的實例 AdomdDatareader 類,它被初始化后用來訪問對列編號了的嵌套表。如果指定的列并不是一個被嵌套的表,“執行”方法將返回一個異常。我們可以使用類似如下代碼的語言來判斷Datareader中的列是不是一個嵌套表:
if (rdr.GetFieldType(1) == typeof(AdomdDataReader) )
{
// 如果進入If循環,rdr的第一列是一個嵌套表
}
在現實生活中,最有可能根據用戶的實際輸入來進行預測。一個常見的Web應用場景是這樣的,用戶給出年齡和汽車的顏色,應用程序代碼產生一個DMX請求來預測該客戶購買商品的清單。當開發者對DMX和相關的數據類型有一個很好的理解的時候,查詢可以使用將客戶錄入的所有字符串連接起來的方式進行創建。 然而,這樣的方法具有潛在的威脅,它可能引起DMX嵌入錯誤或研發錯誤。一種更好的方式是使用參數來建立查詢,將用戶輸入的內容作為參數的值。Adomd.NET對DMX的參數化查詢提供了大量的支持,就像下面的例子一樣。這段代碼不包括讀取返回值的內容,因為它與之前的代碼片段是一樣的。
cmd.CommandText = "SELECT Gender, Products FROM Model2 " +
"NATURAL PREDICTION JOIN "+
"( SELECT @Age AS Age, @Color as CarColor) AS T";
AdomdParameter paramAge, paramColor;
paramAge = cmd.CreateParameter();
paramAge.Direction = ParameterDirection.Input;
paramAge.ParameterName = "Age";
cmd.Parameters.Add(paramAge);
paramColor = cmd.CreateParameter();
paramColor.Direction = ParameterDirection.Input;
paramColor.ParameterName = "Color";
cmd.Parameters.Add(paramColor);
cmd.Parameters["Age"].Value = 30; // 用戶在這里輸入
cmd.Parameters["Color"].Value = "Black"; // 用戶在這里輸入
AdomdDataReader rdr = cmd.ExecuteReader();
請注意,參數不一定非是數值。請考慮這樣的DMX語句:
INSERT INTO MyModel(Col1, Col2)
OPENQUERY(DataSource, "SELECT ColA, ColB FROM Table") AS T
或者是:
SELECT PREDICT(Products, 5) FROM MyModel NATURAL PREDICTION JOIN
OPENQUERY(DataSource, "SELECT ColA, ColB FROM Table") AS T
這兩個語句都用了一個OPENQUERY 函數來描述執行時被服務器使用的表型內容(訓練挖據模型,分別進行預測)。使用Adomd.NET,我們可以使用一個參數來取代OPENQUERY函數,并且向服務器傳輸一些表型內容。查詢可能是這樣的:
INSERT INTO MyModel(Col1, Col2)
@MyTabularContent AS T
或者是:
SELECT PREDICT(Products, 5) FROM MyModel NATURAL PREDICTION JOIN
@MyTabularContent AS T
在這些例子中, 參數 MyTabularContent 可以是一個 數據表(DataTable ) 或者執行一個 IDataReader .NET接口。相比來說,數據表更容易使用, IDataReader 接口具有不需要將所有數據保存在內存中的優勢。 IDataReader 執行的一個例子是客戶端應用執行的SQL查詢所返回的 SqlDatareader 。當然,一個SQL查詢請求也可以在OPENQUERY 功能中被提交,但是這種請求的前提是服務器已經訪問到了SQL數據庫。表型參數為兩種情況所設計:
· 數據庫中的數據是客戶端可見但是服務器端不可見的(這種情況應該使用 IDataReader )
· 數據在客戶端應用程序所占用的內存中( DataTable 可以在這種情況時使用)
Adomd.NET 一個獨有的特點是可以使用XML返回選定的列。Microsoft Analysis Services 2005為指定的查詢返回這樣的列。例如:
SELECT * FROM MyModel.PMML
這個語句將返回PMML 2.1格式下MyModel 模型的內容(即被支持PMML的MyModel使用的數據挖掘算法)。除了例如模型名稱、PMML緩沖區大小這類元信息外,這個語句的返回值還包括指定的列和包含PMML的MODEL_PMML(一種被數據挖掘團隊設計出來的XML格式,用來描述挖掘模型的內容)。
這個XML的內容可以以字符串方式被訪問,但是Adomd.NET擁有分析XML列的能力(基于服務器端發來的指定的列類型來判斷) 并且將它們發布為一個 System.Xml.XmlReader 對象。這些列也可以作為字符串被讀取。以下的示例代碼使用這一特性來訪問帶XML目錄的列,同時使用字符串和 XmlReader 兩種方法。
cmd.CommandText = "SELECT * from [MyModel].PMML";
AdomdDataReader rdr = cmd.ExecuteReader();
// 遍歷響應結果,讀取第5列,MODEL_PMML
while (rdr.Read())
{
// 取得列值
object objXMLValue = rdr.GetValue(5);
if (objXMLValue is System.Xml.XmlReader)
{
//使用一個XML reader
System.Xml.XmlReader pmmlReader =
(System.Xml.XmlReader)objXMLValue;
//在這里讀PMML
}
// 使用字符串來獲取這列
string strPMMLAsString = rdr.GetString(5);
}
Adomd.NET 的另一個特性是連續訪問服務器響應,將在 進度通知:使用跟蹤對象 一節中具體闡述。
Adomd.NET是Microsoft Analysis Services 2005中最具靈活性,最容易使用的客戶端API。在編寫以微軟分析服務為目標的.NET應用操作時也同樣推薦使用它。它提供了類AMO訪問服務器元數據的大量特性,它允許執行DDL和DMX語句,并且它對DMX語句的參數也有很好的支持。
OLE DB作為通用API
在微軟Windows操作系統中,OLE DB是進行數據訪問最常用的API。OLE DB是針對OLE對象的規范。這些OLE對象有一系列標準接口。這些接口的標準化使得一個編程模型幾乎可以訪問所有類型的數據源。微軟SQL Server數據挖掘有一個OLE DB提供程序。這個提供程序能將OLE DB編程模型翻譯成數據挖掘所需要的內容。
關于 OLE DB的更多內容,請訪問MSDN OLE DB頁。
OLE DB可以被很多種編程語言直接使用。在本機(非托管)C++中,可以創建OLE DB對象,并且可以直接調用OLE DB的方法。ALT使用者模版(ALT Consumer Templates)也為OLE DB使用者應用程序提供了一系列有用的類。在Visual Basic或者VBA中,OLE DB提供程序可以在ADO(ActiveX Data Objects,ActiveX數據對象)中使用。在托管語言中,我們可以使用ADO.NET 庫來調用OLE DB提供程序。
OLEDB編程模型以如下對象為中心。首先,數據源必須由服務器端初始化和控制。其次,在這個數據源上必須初始化一個通訊對話。OLE DB架構的第三個重要組成部分就是命令,它們將服務器請求打包。每個服務器請求都是對話的一部分。OLE DB架構的第四個組成部分是服務器響應。大多數數據挖掘任務可以被OLE DB命令所執行。例如,可以使用一個命令來傳輸DMX語句,也可以傳輸一個DDL語句來創建一個新的元數據。但是命令并不能傳輸一個發現元數據語句(Discovery)。所以針對此點,OLE DB定義了一個可以被對話執行的 IDBSchemaRowset 接口。這里我們需要注意的是,ADO和ADO.NET有一個封裝了數據源和OLE DB對話的連接對象(Connection)。這兩種標準的OLE DE對象(數據源和OLE DB對話)公開的功能在ADO和ADO.NET的連接對象中可用。
所有的OLE DB對象(數據源、對話、命令和響應)經常在COM組件中執行來調用OLE提供程序。
下面的圖1給出了一個OLE DB解決方案的框架:
圖 1. OLE DB解決方案框架圖
如圖中所示,首先,各個客戶端上安裝的OLE DB提供程序使用OLE DB來連接服務器。Microsoft Analysis Services 2005的OLE DB提供程序是在安裝SQL Server 2005的連接組件時安裝的。
OLEDB連接經常通過連接字符串的方法來初始化。連接字符串包含一系列有分號分隔開的“名字-值”字符對,即屬性。這些屬性描述了OLE DB連接初始化時的各個參數。所有的OLE DB包(如ATL使用者模版、ADO、或者ADO.NET)都根據連接字符串來進行初始化。這里給出一個用來連接Microsoft Analysis Services 2005的OLE DB連接字符串的例子:
"Provider=MSOLAP; Data Source=localhost; "
第一個屬性 Provider 描述示例中指定的提供程序。
"MSOLAP" 是微軟分析服務中OLE DB提供程序的名字。請注意這個名字是依賴版本的。如果一臺機器上安裝了多個分析服務OLE DB提供程序(如一個來自Analysis Services 2005,一個來自Analysis Services 2000),就需要使用更加準確的名字來區分版本:Analysis Services 2000使用“MSOLAP.2”,Analysis Services 2005使用“MSOLAP.3”。第二個屬性“Data Source”表示要連接的數據源。它一般都是一個機器名,但是也可以是其它表達方式。例如,它可以是一個文件名,或者是一個網絡URL,如我們將在下文“HTTP Pump”章所見到的一樣。關于分析服務OLE DB提供程序屬性的更多信息,你可以從SQL Server在線信息中得到。
下面這段代碼是一個VBA應用程序中使用OLE DB的例子,它使用了ADO。具有相似功能的C#代碼(使用ADO.NET)和非托管C++代碼在附錄2中。
為使用ADO,需要為你的Visual Basic (或者VBA)工程添加一個指向Microsoft ActiveX Data Object庫(你機器中最新版本的庫)的引用。以下的代碼片段是在2.8版本上進行測試的:
1 Dim Conn As ADODB.Connection
2
3 Set Conn = New ADODB.Connection
4 Conn.Open ("Provider=MSOLAP.3; Data Source=localhost;" _
5 & "Initial Catalog=MyCatalog")
在第一行和第三行創建并初始化了一個ADODB連接對象。在第四行,就像我們前邊所說的,ADO連接對象封裝了兩種OLE DB對象:數據源和對話。在連接字符串中,你將看到一個之前沒有討論過的屬性:“Initial Catalog”。它定義服務器上將被這個連接使用的數據庫。讓我們使用這個連接對象來完成我們之前列舉的數據挖掘任務。
對于元數據發現(Discovery),ADO連接提供了一個 OpenSchema 函數(在OLE DB對話中打包了 IDBSchemaRowset 接口)。
OpenSchema 包含3個參數:
· 枚舉,用來描述將要被發現的計劃。
· 約束集,將被應用于發現操作的一系列約束。
· 全局唯一標識符(GUID),描述提供程序指定的計劃。
我們嘗試在MyCatalog 數據庫上發現服務器端的挖掘模型。這不是數據挖掘模型計劃(指定的提供程序計劃)中預先計劃好的枚舉,所以第一個參數就是 adSchemaProviderSpecific 。第二個參數,約束集,包含用來查找模型(“MyCatalog”)的目錄名。第三個參數包含Analysis Services OLE DB提供程序中,能識別挖掘模型計劃的GUID的字符表。
6 Const DMSCHEMA_MINING_MODELS="{3add8a77-d8b9-11d2-8d2a-00e029154fde}"
7 Dim Restrictions()
8 Restrictions = Array("MyCatalog")
9 Dim rsSchema As ADODB.Recordset
10 Set rsSchema = Conn.OpenSchema(
adSchemaProviderSpecific,
Restrictions,
DMSCHEMA_MINING_MODELS)
數據挖掘的OLE DB規范包含分析服務的OLE DB提供程序支持的計劃的完整定義,包括發現(Discovery)語句返回的列和約束。
OpenSchema 返回一個 ADODB.Recordset 對象。 Recordset 對象封裝了一個表型服務器響應。下面我們將看到如何遍歷這個對象以及如何從中提取信息。這段代碼的目的是枚舉挖掘模型的名字。 像我們所知道的一樣,在數據挖掘OLE DB里,挖掘模型計劃中的每一行對應一種挖掘模型,并且包含一個“MODEL_NAME”列,列中存儲挖掘模型的名字。
下面一段代碼顯示如何從 Recordset 對象中查找指定的列,以及如何從這些列中提取信息。
11 ' 從(MODEL_NAME)中查找列
12 Dim iModelNameColumn As Integer
13 For iModelNameColumn = 0 To rsSchema.Fields.Count - 1
14 If rsSchema.Fields(iModelNameColumn).Name = "MODEL_NAME" Then
15 GoTo Found
16 End If
17 Next
18 Error (1)
19 Found:
20 ' 讀取Recordset的返回值
21 rsSchema.MoveFirst
22 While Not rsSchema.EOF
23 Debug.Print rsSchema.Fields(iModelNameColumn).Value
24 rsSchema.MoveNext
25 Wend
如你所看到的一樣,這段代碼先遍歷了 Recordset 對象的所有字段。每個字段表示響應的一列。我們根據這些字段的索引MODEL_NAME進行查找。如果找到了這樣的一列,就開始遍歷它的行內容,否則就報錯。
為了遍歷行, Recordset 指針先移到數據的開始位置。之后一行一行的讀取行數據。對于每一行都讀取和使用MODEL_NAME字段的值。
一些數據挖掘任務(如創建新元數據對象或訓練已存在的對象)可以通過發送DDL語句到服務器來執行。讓我們看看DDL語句是如何被OLE DB通過ADO來傳輸的。我們將使用與之前一樣的連接對象,并介紹一個新的OLE DB對象的ADO包, ADODB.Command 對象:
26 Dim Cmd As ADODB.Command
27 Set Cmd = New ADODB.Command
28 Cmd.ActiveConnection = Conn
29
30 Dim strProcessDDLStmt As String
31 strProcessDDLStmt = "" _
32 & "</Process
xmlns=""http://schemas.microsoft.com/analysisservices/2003/engine"">" _
33 & " <Type>ProcessStructure</Type>" _
34 & " <Object>" _
35 & " <DatabaseID>CheckInTestDB</DatabaseID>" _
36 & " </Object>Structure1" _
37 & " </Process>" _
38 & ""
39
40 Cmd.CommandText = strProcessDDLStmt
41 Cmd.Execute
42
命令在一個活躍連接中執行。這個活躍的連接就是第28行中的內容。一般來說,這個命令包含著執行語句。這在 CommandText 屬性(第40行)中設置。當ADO為Analysis Services 2005打包OLE DB提供程序時, CommandText 屬性支持DMX語句和DDL語句(就像之前所展示的一樣)。命令的執行被“執行(Execute)”方法初始化(第41行)。執行經常返回一個 ADODB.Recordset 對象(可用于之前的發現(Discovery)代碼段的表型服務器響應)。但是,處理操作是沒有服務器響應的,它不返回成功或失敗。如果出現了一個錯誤,ADO將報一個異常并停止正在運行的代碼。因此,如果執行到了第42行,就說明執行成功了。
在之前的代碼中,可以將 CommandText 屬性改為一個DDL語句,比如 Alter 、 Create 或者 Dro p ;或改為一個DMX語句,如CREATE MINING MODEL或者INSERT INTO,它可以實現絕大多數挖掘任務。唯一一個需要附加補充的是查詢挖掘模型。DMX查詢與一般的無響應信息語句不同,因為:
· 它返回一個表型結果。
· 表型結果可能包含多級的表(嵌套表)。
· DMX 支持參數。
我們可以從返回單級表的DMX查詢開始看起,使用我們最開始使用的對象來對比(命令和連接):
43 Cmd.ActiveConnection = Conn
44 Cmd.CommandText = "SELECT NODE_CAPTION FROM DecisionTree1.CONTENT" _
45 &"where NODE_TYPE=2"
46
47 Dim rs As ADODB.Recordset
48 Set rs = Cmd.Execute()
49 rs.MoveFirst
50 While Not rs.EOF
51 Debug.Print rs.Fields(0).Value
52 Wend
53 rs.Close
如我們之前所提到的一樣,DMX語句由 CommandText 屬性來傳輸。與發現(Discovery)使用相同的方式來遍歷 Recordset 。第44行用到的查詢只返回一列,這里并不真正需要從recordset 字段來查找列;相反的,它應該由它的索引得到(第51行)第0字段的內容。也請注意第53行中對 Recordset 的配置。當 Recordset 是活躍的時候,命令對象不能執行之后的語句。
OLE DB規范也允許返回更加復雜的結果集,如表型列或者嵌套表。下面給出一個服務器響應是嵌套表的例子,我們將使用DMX語句來添加查詢更復雜的第二列NODE_DISTRIBUTION。所以新的查詢如下所示:
"SELECT NODE_CAPTION, NODE_DISTRIBUTION FROM DecisionTree1.CONTENT WHERE NODE_TYPE=2"
NODE_DISTRIBUTION 是一個典型的嵌套表例子。根據數據挖掘的OLE DB規范,模型中的NODE_DISTRIBUTION列包含當前行所在節點的屬性值的分布。例如,在一棵預測頭發顏色的決策樹中,對每一個樹節點,這一列都描述有多少實例是黑發,多少實例是金發,多少實例是灰發。
執行命令在新的一列中并不改變。實際上唯一需要改變的就是 Recordset 的遍歷代碼,需要進行適合表的新列的改變。在代碼中可以很容易的從 Recordset 作為字段值的屬性返回一列的值。如果實例中的列是一個嵌套表,列值將產生一個新的 Recordset ,再遍歷整個嵌套表。
所以,在51行以下應該執行如下的代碼:
52 Debug.Assert( rs.Fields(1).Type = adChapter)
53 Dim nestedRS As ADODB.Recordset
54 Set nestedRS = rs.Fields(1)
55 nestedRS.MoveFirst
56 While Not nestedRS.EOF
57 Debug.Print nestedRS.Fields(0).Value
58 Wend
59 nestedRS.Close
第52行語句用來在將值寫入嵌套 Recordset 前,確認列的類型是正確的。這行語句也可以用來判斷制定的列是不是一個嵌套表。
應為擁有遍歷嵌套表的能力,此時數據挖掘查詢產生的任何返回值都可以在你的應用中被使用了。
DMX也支持查詢中的參數。參數可以取代DMX查詢中的任何值。例如,可以使用一個參數來代替上述查詢語句中 where 子句里的NODE_TYPE 的值“2”。在數據挖掘應用中,也有少數參數非常有用的場景,比如生成一個單獨的查詢(關于單獨查詢的詳細內容,請看“Adomd.NET”一節)。
想在DMX查詢中將一個值變為一個參數,我們使用參數指示標志 @ 來開始替換,使用“ @ 唯一的參數名”。這樣VBA代碼片段中的第45行就可以變成:
45 &"where NODE_TYPE=@typeParam"
然后,在執行命令之前,我們應該插入這樣的一段代碼來確保能正確的使用新的參數。請注意,盡管實際數據可能與參數的值很不同,但是使用參數并不會改變服務器響應的格式。所以上述遍歷 Recordset 的代碼可以并不改變。
46 Cmd.NamedParameters = True
47
48 Dim typeParameter As ADODB.Parameter
49 Set typeParameter = Cmd.CreateParameter()
50 typeParameter.Direction = adParamInput
51 typeParameter.Name = "typeParam"
52 typeParameter.Value = 2
53 typeParameter.Type = adInteger
54 typeParameter.Size = 4
55
56 Cmd.Parameters.Append typeParameter
在分析服務的OLE DB提供程序中使用參數時,如下的幾步非常重要:
· 命令必須使NamedParameters可用(第46行)。分析服務的OLE DB提供程序只支持命名了的參數。
· 參數的名字必須符合查詢中的相應參數,但是在這里不使用 @ 前綴(第51行)。
· 可以只傳輸參數(第50行)。
· 參數的類型和大小必須聲明(第53和54行)。
想對數據挖掘的OLE DB規則進行很好的理解,需要充分使用Microsoft Analysis Services 2005數據挖掘的特性。一旦設計好了數據挖掘查詢,OLE DB就成為了一個可以執行它們、可以管理數據挖掘服務器的完整且具有通用性的API。關于在非托管C++或ADO.NET中C#使用OLEDB 的代碼,請看本文附錄2中的代碼片段。
Analysis Management Objects – AMO
如同名字所顯示的一樣,AMO是一個用來管理任務的API。它非常適用于描述元數據屬性的細節信息。AMO是一種非常符合微軟分析服務的數據定義語言(DDL)的對象模型,在AMO中描述元數據對象。它允許迭代元數據對象、創建新對象、修改已存在對象。在AMO對象模型中,用DDL描述的每個屬性都可以被檢查和修改。AMO也可以用來檢查和修改服務器屬性,包括注冊/非注冊型插件算法,或者可注冊/不可注冊數據挖掘算法。AMO在元數據的定義和發現,以及服務器對象的訓練上都非常有用。但是,它并不支持執行查詢語句。
在討論細節信息之前,我們應該先來說明一下AMO是一個托管庫。所以,它可以在由通用執行時間組件(CLR——Common Language Runtime)兼容的編程語言開發的應用程序中使用,如C#、托管執行的C++、或者Visual Basic .NET。要想使用AMO, 我們需要在客戶機上安裝SQL Server 2005連接組件。
在使用AMO的時候,我們首先應該在應用程序的開始處引用 Microsoft.AnalysisServices.dll 庫。之后,AMO對象模型就可以使用了。先來連接服務器:
Microsoft.AnalysisServices.Server server = new Server();
Server.Connect("localhost");
一旦連接成功,服務器端的元數據對象就可以被分級檢查到:
Databases dbCollection = server.Databases;
foreach( Database db in dbCollection )
{
MiningStructures structCollection = db.MiningStructures;
foreach( MiningStructure struct in structCollection)
{
Console.WriteLine( struct.Name );
}
}
如果想修改已存在的元數據對象,我們只需要修改它的屬性。使用如下代碼:
model.Algorithm="Microsoft_Decision_Trees".
then call "Update".
model.Update();
當Update被調用時,你所做的修改就將被提交到服務器,同時刷新本地的信息集。
在服務器上添加一個新的元數據、在各自的集合上創建新成員這兩個方法,與修改功能也是非常相似的:
MiningStructure myStructure;
MiningModel myModel = myStructure.Models.Add();
之后填充對象的內容:
myModel.Name = "New Model"
myModel.Algorithm = "Microsoft_Clustering"
然后通過調用 Update() 來提交對服務器端所作的修改:
myModel.Update();
當操作未能成功執行完畢時,更新操作(Update)將返回一個異常。通常產生異常的情況是:
· 被更新的屬性不完整或者不一致。
· 由于當前用戶未能擁有足夠的權限而引起的服務器不能更新對象。
當出現異常的時候,我們可以找到問題的所在并修復它。
AMO在處理Analysis Services 2005服務器端元數據上具有很強的功能,但是它并不支持之前所提到的數據挖掘任務中的部分任務。它不提供進度通知的功能,也不提供查詢挖掘模型的功能(一般情況下,它不支持DMX語句的執行)。如果你的應用需要瀏覽和檢查Analysis Services 2005服務器,使用AMO是最好的選擇。但是,如果除此以外你還需要執行語句或者顯示進度通知,AMO的功能就不夠了。下一章將為大家介紹兩種通用API,它們支持分析服務所公開的所有特性。
進度通知:使用跟蹤對象
當在服務器端同時執行多個事件時,微軟分析服務就會發送一系列通知。這些事件包括用戶的登入登出、 執行請求的開始位置和結束位置、不同服務器對象正在執行的進度情況。在接收到通知以后,管理員就可以檢查服務器在每一刻的狀態。正在處理服務器對象的用戶也可以從中了解正在執行的操作是什么,以及還需要執行多長時間。
這一節中,我們將討論應用程序是如何從Microsoft Analysis Services 2005服務器來接收進度通知的。我們從如何發現服務器發出的通知看起。 之后,我們簡短的介紹應用程序如何訂閱它所感興趣的服務器通知。最后,我們給出一個需要處理進度通知的應用程序的編程模型。
在進行深入的討論之前,我們先來明確一下,SQL Server 2005使用一個客戶端分析器(Profiler)來處理這些通知。使用這個分析器,用戶可以真正根據自己的需要進行通知的選擇,然后檢查這些通知的具體內容。分析器應用程序也允許記錄服務器通知,可以為了以后檢查通知內容而先將它們保存下來。它也可以使用性能計數器(Performance Counter)將正在執行的不同的性能指示器的相關服務器通知整合起來。大多數應用程序并不需要在代碼中執行服務器通知,這一節針對那些需要使用數據挖掘客戶端高級用戶接口的開發者來進行講解。
服務器發出的每種通知都是一個表型行。這一行包含一些基本信息,例如通知的種類、時間戳、服務器進程ID、以及服務器的名稱。其它列分別對應特定的事件,例如處理通知的Progress Total、起始時間、結束時間、在服務器上已經執行的時間。服務器發出的所有通知被存放在一張虛擬表中,它為每個事件保留一行,以及被任何服務器事件支持的所有列的集合。這意味著:如果列A只被一個指定事件支持,它將在這張虛擬表中所有的事件行中出現,但是不支持A的事件的列A字段是空值。說這張表是一張虛擬表,是因為它并不存放在內存中,也不能被直接訪問到。當沒有人去看服務器事件進展情況的時候,它被存放在一個只有管理員可以訪問到的“flight-recorder”文件中,用來提供過去出現錯誤的原因相關的有價值的信息。
這張虛擬表中的列集可以用常規XMLA發現語句(Discovery)來發現。這個計劃的XMLA名稱是DISCOVER_TRACE_COLUMNS,它的GUID是{a07ccd18-8148-11d0-87bb-00c04fc33942}。這個計劃中的每一行描述事件表中的一列,計劃至少有一列,使用事件的XML格式進行描述。XML格式的描述如下所示:
<COLUMN>
<ID>0</ID>
<TYPE>1</TYPE>
<NAME>EventClass</NAME>
<DESCRIPTION>Event Class is used to categorize events.</DESCRIPTION>
<FILTERABLE>false</FILTERABLE>
<REPEATABLE>false</REPEATABLE>
<REPEATEDBASE>false</REPEATEDBASE>
</COLUMN>
就這本白皮書來說,我們所感興趣的屬性有 ID 、 名字( Name )和描述( Description )。
ID 是列的數值型標志符。像我們關于事件的討論一樣,一個事件通過定義ID來指定列。列的名字和描述對于客戶端來說非常重要。基于這些屬性,客戶端應用程序可以判斷哪些列是自己所感興趣的列,哪些列是可以忽略的。 ID 為 0 的列是“服務器通知”這張虛擬表中最重要的列,因為它是用來定義事件類型的。Microsoft Analysis Services 2005發布的所有通知都包含此列。
發現服務器發布的事件是一個與發現列很相似的任務。使用的XMLA計劃是 DISCOVER_TRACE_EVENT_CATEGORIES,它的GUID是 {a07ccd19-8148-11d0-87bb-00c04fc33942}。這個任務中的每一行描述一個服務器發布的事件類別,任務記錄事件類別中的全部事件。當使用XML形式定義事件類別時,任務中的代碼如下所示:
<EVENTCATEGORY>
<NAME>Queries Events</NAME>
<TYPE>0</TYPE>
<DESCRITION>Collection of events for queries.</DESCRITION>
<EVENTLIST>
<EVENT>
<ID>9</ID>
<NAME>Query Begin</NAME>
<DESCRIPTION>Query begin.</DESCRIPTION>
<EVENTCOLUMNLIST>
<EVENTCOLUMN>
<ID>0</ID>
</EVENTCOLUMN>
<EVENTCOLUMN>
<ID>2<ID>
</EVENTCOLUMN>
...
</EVENTCOLUMNLIST>
</EVENT>
<EVENT>
<ID>10</ID>
<NAME>Query End</NAME>
<DESCRIPTION>Query end.</DESCRIPTION>
<EVENTCOLUMNLIST>
<EVENTCOLUMN>
<ID>0</ID>
</EVENTCOLUMN>
<EVENTCOLUMN>
<ID>2</ID>
</EVENTCOLUMN>
...
</EVENTCOLUMNLIST>
</EVENT>
....
</EVENTLIST>
</EVENTCATEGORY>
所以,一個事件類別可以包含多個帶不同ID的事件。如之前所說的一樣,每個事件擁有它們自己的列,并且它們都包含提供事件類信息的列0。
另一個特殊的列是列1,事件子類(event subclass)。它被多個事件共享。事件子類這一列允許跟蹤用戶,例如,我們可以用它來區一個 ProgressStart 事件到底是來自于數據挖掘,還是OLAP維度處理。如果一個事件中出現了列1,這一列要比其它列的定義復雜一些。如下文所示:
<EVENTCOLUMN>
<ID>1</ID>
<EVENTCOLUMNSUBCLASSLIST>
<EVENTCOLUMNSUBCLASS>
<ID>1</ID>
<NAME>Process</NAME>
</EVENTCOLUMNSUBCLASS>
<EVENTCOLUMNSUBCLASS>
<ID>2</ID>
<NAME>Merge</NAME>
</EVENTCOLUMNSUBCLASS>
...
</EVENTCOLUMNSUBCLASSLIST>
</EVENTCOLUMN>
這個更加復雜的定義描述了當前事件中列1可能出現的所有值的含義。
當一個應用程序決定了它感興趣的事件或者事件列是哪些的時候,它可以訂閱這些信息作為服務器通知。這個訂閱功能在服務器創建跟蹤對象的時候被創建。跟蹤對象的功能與包含服務器通知的虛擬表的視圖的功能相似。除此功能以外,跟蹤對象存有服務器對象的所有屬性。它可以被創建、修改、刪除以及根據許可情況進行約束。一個跟蹤聲明會指定它感興趣的事件(類似于關系型視圖中的WHERE子句)以及事件將返回哪些列。定義跟蹤的DDL可以包含更多的過濾條件,如“只返回那些列C是特定值的返回值”,但是這些過濾條件并不是本文要討論的內容。這些高級選項可以從SQL Server 2005 在線文檔中進行了解,在文檔中有專門一節“跟蹤要素(分析服務腳本語言)”。
讓我們來考慮這樣的一個應用程序,它用來訓練挖掘模型,而且只訂閱了如下進度報告事件:
· Progress Report Begin (事件ID是5)
· Progress Report Current (事件ID是7)
· Progress Report End (事件ID是6)
· Progress Report Error(事件ID是8)
對每一個事件來說,感興趣的列是:
· 列 0, EventClass 。
· 列9, ProgressTotal ,完成當前任務所需要執行的步驟數(此列僅在Progress Report Current事件可用)。
· 列10, IntegerData ,數據挖掘進度通知中的屬性,存儲正在執行的任務的當前步驟(此列僅在Progress Report Current事件可用)。
· 列42, TextData ,包含當前步驟的詳細描述。
我們使用下面的DDL語句創建這個跟蹤:
<Create
xmlns="http://schemas.microsoft.com/analysisservices/2003/engine">
<ObjectDefinition>
<Trace>
<ID>DemoTrace</ID>
<Name>DemoTrace</Name>
<Events>
<Event>
<EventID>5</EventID>
<Columns>
<ColumnID>0</ColumnID>
<ColumnID>42</ColumnID>
</Columns>
</Event>
<Event>
<Event ID>6</Event ID>
<Columns>
<ColumnID>0</ColumnID>
<ColumnID>42</ColumnID>
</Columns>
</Event>
<Event>
<EventID>7</EventID>
<Columns>
<ColumnID>0</ColumnID>
<ColumnID>9</ColumnID>
<ColumnID>10</ColumnID>
<ColumnID>42</ColumnID>
</Columns>
</Event>
<Event>
<EventID>8</EventID>
<Columns>
<Columns>0</Columns>
<Columns>42</Columns>
</Columns>
</Event>
</Events>
</Trace>
</ObjectDefinition>
</Create>
一旦跟蹤被創建,客戶端應用程序就將訂閱這個跟蹤。訂閱跟蹤的功能與執行返回表型
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
