我正在尝试构建一个SSIS脚本任务,该任务将根据数据库视图中的分区列表检查SSAS多维数据集上的分区名称。如果分区存在但不在列表中,则将其删除,否则将对其进行处理。
如果分区将删除,该脚本似乎可以正常工作,但是它似乎无法继续循环并使用drop生成枚举错误,如下所示:
运行仅尝试处理的脚本(即null
和Play
没有rowCount == 1
条件)运行良好并且完成且没有错误。看来我在循环浏览它的集合时无法删除分区。如果在SQL查找表中找到这些分区,我将不胜感激如何删除这些分区。
pt.Process()
答案 0 :(得分:1)
它告诉您,在循环播放时,您无法修改正在循环的集合。
因此,解决这个问题的一种方法是在foreach
循环中放弃分区。而是将其添加到数组或字符串构建器或您选择的其他新创建的集合中。
然后在foreach
循环之后循环遍历新创建的集合,并删除与集合的每个成员关联的分区。
答案 1 :(得分:1)
以下是Tab Alleman将其添加到集合中的解决方案。完成查询服务器本身后,分区列表在第二个foreach
循环中循环。我创建了一个新的XmlaWarningCollection
并从那里删除,这似乎维持了连接。它会丢弃我的数据库视图中未列出的所有分区。
可以在此Microsoft博客上找到进一步的帮助: https://blogs.msdn.microsoft.com/rafats/2009/02/10/how-to-partition-cube-using-c/
public void Main()
{
try
{
String Server = Dts.Variables["User::Connection"].Value.ToString();
String Cube = "TestCube";
String conn = "Provider=MSOLAP;Data Source=" + Server + ";";
Server MDXServer = new Server();
MDXServer.Connect(conn);
//Add collection to contain partitions to be dropped
List<Partition> partitions = new List<Partition>();
foreach (Database db in MDXServer.Databases)
{
foreach (Cube cb in db.Cubes)
{
if (cb.Name == Cube)
{
foreach (MeasureGroup mg in cb.MeasureGroups)
{
foreach (Partition pt in mg.Partitions)
{
string PartName = (pt.Name.ToString());
//Create SQL query to reference the parition view and check row count when partition name used in predicate:
string sqlString = "SELECT COUNT(*) FROM [dim].[Partitions] WHERE [Partition] = @pt;";
// Open DB connection:
ConnectionManager cm;
cm = Dts.Connections["Server_Alias"];
SqlConnection connection = (SqlConnection)cm.AcquireConnection(Dts.Transaction);
// Link the query and the connection string together as a command
SqlCommand cmd = new SqlCommand(sqlString, connection);
// Add a value to the parameter in the SQL query
cmd.Parameters.AddWithValue("@pt", PartName);
// Activate reader to read the resulting data set from the query
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read()) //while loop performs an action whilst the reader is open
{
// Put the result of query into a string variable in the script task
string rowCount = reader[0].ToString();
//if the partition exists but is not in the database dim.Partitions view, drop from collection.
if (rowCount == "0")
{
partitions.Add(pt);
}
}
//End the read loop
reader.Close();
}
}
}
}
}
//Loop through the collection created in the above foreach loop and drop the partitions in it from the server.
foreach (Partition dropPartition in partitions)
{
XmlaWarningCollection warningColln = new XmlaWarningCollection();
dropPartition.Drop(DropOptions.Default, warningColln);
}
Dts.TaskResult = (int)ScriptResults.Success;
}
catch (Exception ex)
{
//catch error and return error to package for logging
Dts.Events.FireError(0, "Script task error: ", ex.Message + "\r" + ex.StackTrace, String.Empty, 0);
Dts.TaskResult = (int)ScriptResults.Failure;
}
}