ユーザー定義関数およびストアド プロシージャ
ADOMD.NET サーバー オブジェクトを使用すると、サーバーから取得したメタデータやデータを Microsoft SQL Server Analysis Services で操作するためのユーザー定義関数 (UDF) またはストアド プロシージャを作成できます。 これらのインプロセス メソッドは、ネットワーク通信に関連する待機時間を伴わず、追加機能を提供する多次元式 (MDX) ステートメントまたはデータ マイニング拡張機能 (DMX) ステートメントを通して呼び出されます。
UDF の例
UDF は、MDX ステートメントまたは DMX ステートメントのコンテキスト内で呼び出すことができます。また、任意の数のパラメーターを取り、任意の型のデータを返します。
MDX を使用して作成された UDF は、DMX の UDF と似ています。 主な相違点は、Context オブジェクトの一部のプロパティ (CurrentCube、CurrentMiningModel など) は、いずれか 1 つのスクリプト言語でしか使用できないということです。
次の例では、UDF を使用して、ノードの記述を取得し、組をフィルターし、組に対してフィルターを適用する方法を示します。
ノードの記述を取得する
次の例では、指定されたノードのノード記述を返す UDF を作成します。 UDF は、UDF が実行されている現在のコンテキストを使用し、DMX FROM 句を使用して現在のマイニング モデルからノードを取得します。
public string GetNodeDescription(string nodeUniqueName)
{
return Context.CurrentMiningModel.GetNodeFromUniqueName(nodeUniqueName).Description;
}
前の例の UDF を配置すると、次の DMX 式で呼び出せるようになります。この式は、最も可能性が高い予測ノードを取得します。 ノード記述には、予測ノードを構成する条件についての情報が含まれます。
select Cluster(), SampleAssembly.GetNodeDescription( PredictNodeId(Cluster()) ) FROM [Customer Clusters]
組を返す
次の例は、セットおよび返される回数を受け取り、そのセットからランダムに組を取得し、最後のサブセットを返します。
public Set RandomSample(Set set, int returnCount)
{
//Return the original set if there are fewer tuples
//in the set than the number requested.
if (set.Tuples.Count <= returnCount)
return set;
System.Random r = new System.Random();
SetBuilder returnSet = new SetBuilder();
//Retrieve random tuples until the return set is filled.
int i = set.Tuples.Count;
foreach (Tuple t in set.Tuples)
{
if (r.Next(i) < returnCount)
{
returnCount--;
returnSet.Add(t);
}
i--;
//Stop the loop if we have enough tuples.
if (returnCount == 0)
break;
}
return returnSet.ToSet();
}
前の例は、次の MDX 式で呼び出されます。 この MDX の例では、Adventure Works データベースから 5 つのランダムな都道府県が取得されます。
SELECT SampleAssembly.RandomSample([Geography].[State-Province].Members, 5) on ROWS,
[Date].[Calendar].[Calendar Year] on COLUMNS
FROM [Adventure Works]
WHERE [Measures].[Reseller Freight Cost]
組に対してフィルターを適用する
次の例では、UDF は、セットを受け取り、Expression オブジェクトを使用してそのセット内の各組に対してフィルターを適用するように定義されます。 フィルターの条件に合う組は、返されるセットに追加されます。
public static Set FilterSet(Set set, String filterExpression)
{
Expression expr = new Expression(filterExpression);
SetBuilder resultSetBuilder = new SetBuilder();
foreach (Tuple tuple in set)
{
if ((bool)(expr.Calculate(tuple)))
{
resultSetBuilder.Add(tuple);
}
}
return resultSetBuilder.ToSet();
}
前の例は、次の MDX 例で呼び出されます。この MDX 例は、セットにフィルターを適用し、名前が "A" で始まる都市だけに絞り込みます。
Select Measures.Members on Rows,
SampleAssembly.FilterSet([Customer].[Customer Geography].[City], "[Customer].[Customer Geography].[City].CurrentMember.Name < 'B'") on Columns
From [Adventure Works]
ストアド プロシージャの例
次の例では、MDX ベースのストアド プロシージャが AMO を使用して、必要に応じて Internet Sales のパーティションを作成します。
public static void CreateInternetSalesMeasureGroupPartitions()
{
//Check the current state of the data warehouse and
//create partitions with AMO if necessary
#region Retrieve order date of last sales transaction
// Open a connection to the data warehouse
// TODO: Change the first string parameter to reflect the right server\instance.
SqlConnection conn = new SqlConnection(string.Format("data source={0};initial catalog={1};Integrated Security=SSPI", "server\\instance", Context.CurrentDatabaseName));
conn.Open();
// Create a command
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
// Get the order date key of the last internet sale
int lastInternetSaleDateKey = 0;
cmd.CommandText = "select max(OrderDateKey) from FactInternetSales";
lastInternetSaleDateKey = (int)cmd.ExecuteScalar();
// Get the order date key of the last reseller sale
int lastResellerSaleDateKey = 0;
cmd.CommandText = "select max(OrderDateKey) from FactResellerSales";
lastResellerSaleDateKey = (int)cmd.ExecuteScalar();
#endregion
#region Create partitions
// Connect to the calling session
Server svr = new Server();
svr.Connect("*");
// Get the Adventure Works cube
Database db = svr.Databases.GetByName(Context.CurrentDatabaseName);
Cube cube = db.Cubes[0];
MeasureGroup mg;
int maxOrderDateKey;
mg = cube.MeasureGroups.GetByName("Internet Sales");
maxOrderDateKey = 0;
foreach (Partition part in mg.Partitions)
{
maxOrderDateKey = Math.Max(maxOrderDateKey, Convert.ToInt32(
part.Annotations.Find("LastOrderDateKey").Value.Value,
System.Globalization.CultureInfo.InvariantCulture));
}
if (maxOrderDateKey < lastInternetSaleDateKey)
{
Partition part = mg.Partitions.Add("Internet_Sales_"
+ lastInternetSaleDateKey);
part.StorageMode = StorageMode.Molap;
part.Source = new QueryBinding(db.DataSources[0].ID,
"SELECT * FROM [dbo].[FactInternetSales] WHERE OrderDateKey > '"
+ maxOrderDateKey + "' and OrderDateKey <= '" + lastInternetSaleDateKey + "'");
part.Annotations.Add("LastOrderDateKey", Convert.ToString(lastInternetSaleDateKey,
System.Globalization.CultureInfo.InvariantCulture));
part.Update();
part.Process();
}
svr.Disconnect();
#endregion
}