2016-11-01 2 views
0

데이터베이스보기의 파티션 목록에 대해 SSAS 큐브의 파티션 이름을 검사하는 SSIS 스크립트 작업을 작성하려고합니다. 파티션이 있지만 목록에 없으면 삭제됩니다. 그렇지 않으면 처리됩니다.AMO - foreach 루프를 사용하여 SQL 조회를 기반으로 동적으로 파티션을 분할합니다.

는 스크립트가 지금까지 파티션 로 작업 표시

삭제됩니다 , 그러나 그것은 루프를 계속할 수 없습니다 표시하고 다음과 같이 드롭 열거 오류가 발생 :

Enum error whilst dropping partition

실행을 대신 스크립트 (예 : rowCount == 1pt.Process()이없고 else이없는 경우)가 제대로 작동하고 오류없이 완료됩니다. 파티션을 반복하면서 파티션을 삭제할 수없는 것으로 보입니다. 포인터가 SQL 조회 테이블에서 발견되면이 파티션을 삭제하는 방법에 대해 고맙게 생각합니다.

public void Main() 
    { 
     try 
     { 
      String Server = Dts.Variables["User::Connection"].Value.ToString(); 
      String Cube = "CubeName"; 
      String conn = "Provider=MSOLAP;Data Source=" + Server + ";"; 


      Server MDXServer = new Server(); 
      MDXServer.Connect(conn); 

      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 [FinWeek] = @pt;"; 
           // Open DB connection: 
           ConnectionManager cm; 
           cm = Dts.Connections["FIP_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 second result of query (0 woudl be first) 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") 
            { 
             pt.Drop(); 
            } 
           } 
           //End the read loop 
           reader.Close(); 

          } 
         } 
        } 
       } 
      } 
     } 



     catch (Exception ex) 
     { 
      MessageBox.Show(ex.ToString()); 
     } 


     Dts.TaskResult = (int)ScriptResults.Success; 
    } 

답변

1

다음은 Tab Alleman의 조종사가 컬렉션에 추가 한 해결책입니다. 파티션 목록은 서버 자체에 쿼리를 마친 후 두 번째 루프 foreach에 반복됩니다. 새로운 XmlaWarningCollection을 생성하고 거기에서 드롭하면 연결을 유지하는 것처럼 보입니다. 그것은 내 데이터베이스보기에 나열되지 않은 모든 파티션을 삭제합니다.

또한 도움

이 마이크로 소프트 블로그에서 확인할 수 있습니다 : 응답에 대한 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; 
     } 



    } 
1

루프를 반복하는 동안 반복 할 컬렉션을 수정할 수 없다는 것을 알려줍니다.

루프가 foreach 루프에있는 동안 파티션을 삭제하지 않는 것이 좋습니다. 대신 배열이나 문자열 작성자 또는 새로 만든 선택한 컬렉션에 추가하십시오.

그런 다음 foreach 루프 후에 새로 만든 컬렉션을 반복하고 컬렉션의 각 구성원과 관련된 파티션을 삭제하십시오.

+0

감사합니다. 지금 가지고있는 문제는 컬렉션이 서버 객체에 연결되어 있지 않다는 것입니다. 원래의 질문에 수정 된 코드가 있습니다. – TJB

+0

정확히 말하자면, 'partitions' 콜렉션을 반복해야하고 큐브/측정 값 그룹에 연결해야하는 각 구성원에 대해 해당 특정 파티션에 대한 "연결"참조를 작성한 다음 삭제하십시오. –

+0

코드를 다시 편집하여 서버 연결 오류가 발생했습니다. 내 구문을보고 내가 잘못 가고있는 것을 지적 해 주시겠습니까? 다시 한번 감사드립니다. – TJB

관련 문제