{"id":13,"date":"2007-04-18T22:07:51","date_gmt":"2007-04-19T03:07:51","guid":{"rendered":"http:\/\/www.ssas-info.com\/VidasMatelisBlog\/?p=13"},"modified":"2009-07-05T20:10:12","modified_gmt":"2009-07-06T01:10:12","slug":"ssis-package-to-dropcreate-partitions-based-on-partition-list-in-the-sql-server-table","status":"publish","type":"post","link":"http:\/\/www.ssas-info.com\/VidasMatelisBlog\/13_ssis-package-to-dropcreate-partitions-based-on-partition-list-in-the-sql-server-table","title":{"rendered":"SSIS Package to drop\/create partitions based on partition list in the SQL Server table"},"content":{"rendered":"<p>In my past blogs I showed how to use SSIS package to process dimensions, cubes or build aggregates. I am slowly rebuilding my existing packages thanks to points from <a href=\"http:\/\/geekswithblogs.net\/darrengosbell\/Default.aspx\" target=\"_blank\">Darren Gosbell<\/a> and <a href=\"http:\/\/jesseorosz.spaces.live.com\" target=\"_blank\">Jess Orosz<\/a>. I found that using CaptureXML method is more convenient for me and it is definitely faster.<br \/>\n<!--more--><br \/>\nJust to explain again about this method. I can change Analysis Services objects (create, drop, process) in the script using AMO commands. Normally each AMO command is executed in a separate batch. But AMO has an option to save XMLA script from the multiple AMO commands and then submit them in one batch. This is done my assigning Analysis Services server property CaptureXML value &#8216;True&#8217; (to start capturing XMLA) or &#8216;False&#8217; (to stop capturing XMLA). Then XMLA log can be executed using ExecuteCaptureLog statement where first parameter specifies if statements have to be run in batch.<\/p>\n<p>Past weekend I had some time to rewrite my partition synchronization package to use CaptureXML method. I maintain a list of partitions in SQL Server database table iwSSASPartitions. I use a SSIS script to drop partitions if they do not exists in my partition table and create new partitions if they do not exists in SSAS database. I have a SQL Server table with the list of partitions that should exist in SSAS database. Here is the script to create this table:<\/p>\n<blockquote><p>CREATE TABLE [dbo].[iwSSASPartitions](<br \/>\n\u00a0[Partition] [varchar](100) NOT NULL,<br \/>\n\u00a0[CubeName] [varchar](100) NOT NULL,<br \/>\n\u00a0[MeasureGroup] [varchar](100) NOT NULL,<br \/>\n\u00a0[SQL] [varchar](4000) NOT NULL,<br \/>\n\u00a0[NeedsReProcessing] [bit] NOT NULL,<br \/>\n\u00a0CONSTRAINT [PK_iwSSASPartitions] PRIMARY KEY CLUSTERED ( [Partition], [CubeName], [MeasureGroup])<br \/>\n)<\/p><\/blockquote>\n<p>Normally I would deploy SSAS database (no processing) with just one partition per measure group. Then I would run my SSIS package to synchronize partitions between SQL Server table and SSAS database. For initial deployment I would drop about 35 partitions and then create about 250 new partitions. During normal monthly load I would need to create about 30 partitions.<\/p>\n<p>My old package was runnign XMLA scripts to create\/drop partitions. I was creating\/dropping partitions one by one. With old method my initial drop of 35 partition was taking about 5 min. Step to create new 250 partitions was taking about 15 min. As this is not done everyday, 20min to me seemed like a reasonable time. But after I re-wrote my package to take advantage of batch executions, step that drops partitions run for 15 seconds and step that create partitions run for 30 seconds. At first I actually thought that my code is not executing! So this is power of executing XMLA in the batch! <!--more--><\/p>\n<p>Steps to create SSIS package that drops\/create partitions based on partition list in the SQL Server table:<\/p>\n<ul>\n<li>Create new connection to SQL Server database that contains SQL table with list of partitions. It is important here that connection type is ADO.NET and not OLE DB. I had to use ADO.NET connection as I wanted to pass query result as parameter into Script task.<\/li>\n<li>Create new connection to SSAS database. Name that connection DM<\/li>\n<li>Create new variable with Scope package, name &#8220;<span style=\"font-size: 12pt; font-family: 'Times New Roman';\">PartitionListInDW&#8221; and type &#8220;Object&#8221;. This variable will contain list of partitions from table.<\/span><\/li>\n<li>Add new &#8220;Execute SQL Task&#8221; component in Control Flow area. Change following properties for this control:\n<ul>\n<li>ResultSet: &#8220;Full Result Set&#8221;<\/li>\n<li>ConnectionType: &#8220;ADO.NET&#8221;<\/li>\n<li>Connection: From drop down list choose connection you create in first step<\/li>\n<li>SQLStatement: SELECT CubeName,MeasureGroup, Partition, SQL FROM dbo.iwSSASPartitions ORDER BY 1,2,3<\/li>\n<li>In ResultSet tab click &#8220;Add&#8221; and enter 0 for &#8220;ResultName&#8221; and for &#8220;VariableName&#8221; choose &#8220;user::PartitionListInDW&#8221;<\/li>\n<li>Change step name and description to your liking and click OK.<\/li>\n<\/ul>\n<\/li>\n<li>Add new &#8220;Script Task&#8221; component and connect it to prevoiusly create task. In &#8220;Script&#8221; tab change property &#8220;ReadOnlyVariables&#8221; to &#8220;PartitionListInDW&#8221; and click on &#8220;Design Script&#8221; button. In &#8220;Project Explorer&#8221; add reference to &#8220;Analysis Management Objects&#8221; and &#8220;System.XML.dll&#8221;. Rename this component to &#8220;Drop Partitions&#8221;. Add following code:<\/li>\n<\/ul>\n<blockquote><p>Imports System<br \/>\nImports System.Data<br \/>\nImports System.Math<br \/>\nImports Microsoft.SqlServer.Dts.Runtime<\/p>\n<p>Imports Microsoft.AnalysisServices<\/p>\n<p>Public Class ScriptMain<\/p>\n<p>Public Sub Main()<\/p>\n<p>\u00a0 Dim ExecutionSuccessfull As Boolean = True &#8216; If true, package executed without errors<br \/>\n\u00a0 Dim dataBytes(0) As Byte<\/p>\n<p>\u00a0 Dim PartListInDM(999, 2) As String &#8216; expecting no more than a 1000 partitions.<br \/>\n\u00a0 Dim DropPartCount As Integer = 0<\/p>\n<p>\u00a0 &#8216;\u00a0Following objects are used to capture execution results<br \/>\n\u00a0 Dim oResults As Microsoft.AnalysisServices.XmlaResultCollection<br \/>\n\u00a0 Dim oResult As Microsoft.AnalysisServices.XmlaResult<br \/>\n\u00a0 Dim oMessage As Microsoft.AnalysisServices.XmlaMessage<\/p>\n<p>\u00a0 Dim oPartitionList As Variable = Dts.Variables(&#8220;PartitionListInDW&#8221;) &#8216; From variable<br \/>\n\u00a0 Dim oDS As DataSet = CType(oPartitionList.Value, DataSet)<\/p>\n<p>\u00a0 Dim oTbl As DataTable = oDS.Tables(0)<br \/>\n\u00a0 Dim oRow As DataRow<br \/>\n\u00a0 Dim oConnection As ConnectionManager<br \/>\n\u00a0 oConnection = Dts.Connections(&#8220;DM&#8221;)<br \/>\n\u00a0 Dim sServer As String = CStr(oConnection.Properties(&#8220;ServerName&#8221;).GetValue(oConnection))<br \/>\n\u00a0 Dim sDatabase As String = CStr(oConnection.Properties(&#8220;InitialCatalog&#8221;).GetValue(oConnection))<\/p>\n<p>\u00a0 Dim oServer As New Microsoft.AnalysisServices.Server<br \/>\n\u00a0 oServer.Connect(sServer) &#8216; connect to the server and start scanning down the object hierarchy<br \/>\n\u00a0 Dim oDB As Microsoft.AnalysisServices.Database = oServer.Databases.FindByName(sDatabase)<\/p>\n<p>\u00a0 If oDB Is Nothing Then<br \/>\n\u00a0\u00a0\u00a0 Dts.Log(&#8220;Did not find expected database: &#8221; &amp; sDatabase, 0, dataBytes) &#8216; You need to setup proper package loging to see this!<br \/>\n\u00a0\u00a0\u00a0 ExecutionSuccessfull = False<br \/>\n\u00a0\u00a0\u00a0 GoTo Done<br \/>\n\u00a0 End If<\/p>\n<p>\u00a0 Dim oCube As Microsoft.AnalysisServices.Cube<br \/>\n\u00a0 Dim oMeasureGroup As Microsoft.AnalysisServices.MeasureGroup<br \/>\n\u00a0 Dim oPartition As Microsoft.AnalysisServices.Partition<br \/>\n\u00a0 Dim bNeedToDropPartition As Boolean<br \/>\n\u00a0 For Each oCube In oDB.Cubes<br \/>\n\u00a0\u00a0\u00a0 For Each oMeasureGroup In oCube.MeasureGroups<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0 For Each oPartition In oMeasureGroup.Partitions<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8216; Check if this partition exists in our partition table<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0 bNeedToDropPartition = True<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0&#8216; oTbl.Reset()<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0 For Each oRow In oTbl.Rows<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0 If oRow(&#8220;CubeName&#8221;).ToString = oCube.Name.ToString And oRow(&#8220;MeasureGroup&#8221;).ToString =\u00a0\u00a0\u00a0\u00a0 oMeasureGroup.Name.ToString _<br \/>\n\u00a0 And oRow(&#8220;Partition&#8221;).ToString = oPartition.Name.ToString Then<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 bNeedToDropPartition = False &#8216; Found partition in DW list, no need to drop it<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0 Exit For<br \/>\n\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0 End If<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0Next<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0 If bNeedToDropPartition Then<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0 PartListInDM(DropPartCount, 0) = oCube.Name<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0PartListInDM(DropPartCount, 1) = oMeasureGroup.Name<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0 PartListInDM(DropPartCount, 2) = oPartition.Name<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0 DropPartCount = DropPartCount + 1<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0 Dts.Log(&#8220;Found partition that needs to be dropped: &#8221; &amp; oPartition.Name, 0, dataBytes) &#8216; You need to setup proper package loging to see this!<br \/>\n\u00a0 &#8216;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 oPartition.Drop()<br \/>\n\u00a0\u00a0\u00a0\u00a0 \u00a0 End If<br \/>\n\u00a0\u00a0 \u00a0 Next<br \/>\n\u00a0\u00a0 Next<br \/>\n\u00a0 Next<br \/>\n\u00a0 &#8216; MsgBox(DropPartCount)<\/p>\n<p>\u00a0 oServer.CaptureXml() = True<br \/>\n\u00a0 Dim i As Integer = 0<br \/>\n\u00a0 For i = 0 To DropPartCount &#8211; 1<br \/>\n\u00a0\u00a0\u00a0 oCube = oDB.Cubes.FindByName(PartListInDM(i, 0))<br \/>\n\u00a0\u00a0\u00a0 oMeasureGroup = oCube.MeasureGroups.FindByName(PartListInDM(i, 1))<br \/>\n\u00a0\u00a0\u00a0 oPartition = oMeasureGroup.Partitions.FindByName(PartListInDM(i, 2))<br \/>\n\u00a0\u00a0\u00a0 oPartition.Drop()<br \/>\n\u00a0 Next i<br \/>\n\u00a0 oServer.CaptureXml() = False<br \/>\n\u00a0 &#8216; Executing log that contains all XMLA commands<br \/>\n\u00a0 oResults = oServer.ExecuteCaptureLog(True, False)<br \/>\n\u00a0 &#8216;Log the errors and warnings<br \/>\n\u00a0 For Each oResult In oResults<br \/>\n\u00a0\u00a0\u00a0 For Each oMessage In oResult.Messages<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 If oMessage.GetType.Name = &#8220;XmlaError&#8221; Then<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0 &#8216;The processing failed<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0 Dts.Log(oMessage.Description, 0, dataBytes) &#8216; You need to setup proper package loging to see this!<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0 ExecutionSuccessfull = False<br \/>\n\u00a0\u00a0\u00a0\u00a0 \u00a0 Else<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0 &#8216;It is\u00a0just a warning.<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0 ExecutionSuccessfull = True &#8216; if you want to fail on warning, change this to False<br \/>\n\u00a0\u00a0\u00a0 \u00a0 End If<br \/>\n\u00a0\u00a0\u00a0 Next oMessage<br \/>\n\u00a0 Next oResult<br \/>\n\u00a0 &#8216; Finished code that drops partitions<br \/>\n\u00a0 &#8216; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>Done:<br \/>\n\u00a0 oServer.Disconnect()<\/p>\n<p>\u00a0 If ExecutionSuccessfull Then<br \/>\n\u00a0\u00a0\u00a0 Dts.TaskResult = Dts.Results.Success<br \/>\n\u00a0 Else<br \/>\n\u00a0 \u00a0 Dts.TaskResult = Dts.Results.Failure<br \/>\n\u00a0 End If<\/p>\n<p>End Sub<\/p>\n<p>End Class<\/p><\/blockquote>\n<ul>\n<li>Few notes about last script:\n<ul>\n<li>Trying to run dropping of partitions in a single batch in parallel (ExecuteCaptureLog(True, True)) generated error: &#8220;The Delete element at line 9, column 94 (namespace <a href=\"http:\/\/schemas.microsoft.com\/analysisservices\/2003\/engine\">http:\/\/schemas.microsoft.com\/analysisservices\/2003\/engine<\/a>) cannot appear under Envelope\/Body\/Execute\/Command\/Batch\/Parallel&#8221;<\/li>\n<li>You cannot drop partition in For Each partition loop. This is because dropping would change list of members in For each statement. That is way I save all partitions that have to be dropped in array and drop it latter.<\/li>\n<li>You need to enable proper package and (!) step logging to see errors\/warnings in the log<\/li>\n<\/ul>\n<\/li>\n<li>Add new &#8220;Script Task&#8221; component and connect it to prevoiusly create task. In &#8220;Script&#8221; tab change property &#8220;ReadOnlyVariables&#8221; to &#8220;PartitionListInDW&#8221; and click on &#8220;Design Script&#8221; button. In &#8220;Project Explorer&#8221; add reference to &#8220;Analysis Management Objects&#8221; and &#8220;System.XML.dll&#8221;. Rename this component to &#8220;Create New Partitions&#8221;. Add following code:<\/li>\n<\/ul>\n<blockquote><p>Imports System<br \/>\nImports System.Data<br \/>\nImports System.Math<br \/>\nImports Microsoft.SqlServer.Dts.Runtime<\/p>\n<p>Imports Microsoft.AnalysisServices<\/p>\n<p>Public Class ScriptMain<\/p>\n<p>Public Sub Main()<\/p>\n<p>\u00a0 Dim ExecutionSuccessfull As Boolean = True &#8216; If true, package executed without errors<br \/>\n\u00a0 Dim dataBytes(0) As Byte<\/p>\n<p>\u00a0 &#8216; Following objects are used to capture execution results<br \/>\n\u00a0 Dim oResults As Microsoft.AnalysisServices.XmlaResultCollection<br \/>\n\u00a0 Dim oResult As Microsoft.AnalysisServices.XmlaResult<br \/>\n\u00a0 Dim oMessage As Microsoft.AnalysisServices.XmlaMessage<\/p>\n<p>\u00a0 Dim oPartitionList As Variable = Dts.Variables(&#8220;PartitionListInDW&#8221;) &#8216; From variable<br \/>\n\u00a0 Dim oDS As DataSet = CType(oPartitionList.Value, DataSet)<\/p>\n<p>\u00a0 Dim oTbl As DataTable = oDS.Tables(0)<br \/>\n\u00a0 Dim oRow As DataRow<br \/>\n\u00a0 Dim oConnection As ConnectionManager<br \/>\n\u00a0 oConnection = Dts.Connections(&#8220;DM&#8221;)<br \/>\n\u00a0 Dim sServer As String = CStr(oConnection.Properties(&#8220;ServerName&#8221;).GetValue(oConnection))<br \/>\n\u00a0 Dim sDatabase As String = CStr(oConnection.Properties(&#8220;InitialCatalog&#8221;).GetValue(oConnection))<\/p>\n<p>\u00a0 Dim oServer As New Microsoft.AnalysisServices.Server<br \/>\n\u00a0 oServer.Connect(sServer) &#8216; connect to the server and start scanning down the object hierarchy<br \/>\n\u00a0 Dim oDB As Microsoft.AnalysisServices.Database = oServer.Databases.FindByName(sDatabase)<\/p>\n<p>\u00a0 If oDB Is Nothing Then<br \/>\n\u00a0\u00a0\u00a0 Dts.Log(&#8220;Did not find expected database: &#8221; &amp; sDatabase, 0, dataBytes) &#8216; You need to setup proper package loging to see this!<br \/>\n\u00a0\u00a0\u00a0 ExecutionSuccessfull = False<br \/>\n\u00a0\u00a0\u00a0 GoTo Done<br \/>\n\u00a0 End If<\/p>\n<p>\u00a0 Dim oCube As Microsoft.AnalysisServices.Cube<br \/>\n\u00a0 Dim oMeasureGroup As Microsoft.AnalysisServices.MeasureGroup<br \/>\n\u00a0 Dim oPartition As Microsoft.AnalysisServices.Partition<\/p>\n<p>\u00a0 oServer.CaptureXml() = True<br \/>\n\u00a0 For Each oRow In oTbl.Rows<br \/>\n\u00a0\u00a0\u00a0 oCube = oDB.Cubes.FindByName(oRow(&#8220;CubeName&#8221;).ToString)<br \/>\n\u00a0\u00a0\u00a0 If oCube Is Nothing Then<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0 Dts.Log(&#8220;Did not find cube: &#8221; &amp; oRow(&#8220;CubeName&#8221;).ToString, 0, dataBytes) &#8216; You need to setup proper package loging to see this!<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0 Continue For<br \/>\n\u00a0\u00a0\u00a0 End If<br \/>\n\u00a0\u00a0\u00a0 oMeasureGroup = oCube.MeasureGroups.FindByName(oRow(&#8220;MeasureGroup&#8221;).ToString)<br \/>\n\u00a0\u00a0\u00a0 If oMeasureGroup Is Nothing Then<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0 Dts.Log(&#8220;Did not find measure group: &#8221; &amp; oRow(&#8220;MeasureGroup&#8221;).ToString, 0, dataBytes) &#8216; You need to setup proper package loging to see this!<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0 Continue For<br \/>\n\u00a0\u00a0\u00a0 End If<br \/>\n\u00a0\u00a0\u00a0 oPartition = oMeasureGroup.Partitions.FindByName(oRow(&#8220;Partition&#8221;).ToString)<br \/>\n\u00a0\u00a0\u00a0 If (oPartition Is Nothing) Then<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0 Dts.Log(&#8220;Need to create partition: &#8221; &amp; oRow(&#8220;Partition&#8221;).ToString, 0, dataBytes) &#8216; You need to setup proper package loging to see this!<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0 oPartition = oMeasureGroup.Partitions.Add(oRow(&#8220;Partition&#8221;).ToString)<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0 oPartition.StorageMode = StorageMode.Molap<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0 oPartition.Source = New QueryBinding(oDB.DataSources(0).ID, oRow(&#8220;SQL&#8221;).ToString)<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0 If oMeasureGroup.AggregationDesigns.Count &gt; 0 Then &#8216;<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 oPartition.AggregationDesignID = oMeasureGroup.AggregationDesigns(0).ID &#8216; Taking first available aggregation design!<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0 End If<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0 oPartition.Update(UpdateOptions.ExpandFull)<br \/>\n\u00a0\u00a0\u00a0 End If<br \/>\n\u00a0\u00a0Next<br \/>\n\u00a0 oServer.CaptureXml() = False<\/p>\n<p>\u00a0 &#8216;\u00a0Executing log that contains all XMLA commands<br \/>\n\u00a0 oResults = oServer.ExecuteCaptureLog(True, False)<\/p>\n<p>\u00a0 &#8216;Log the errors and warnings<br \/>\n\u00a0 For Each oResult In oResults<br \/>\n\u00a0\u00a0\u00a0 For Each oMessage In oResult.Messages<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0 If oMessage.GetType.Name = &#8220;XmlaError&#8221; Then<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8216;The processing failed<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Dts.Log(oMessage.Description, 0, dataBytes) &#8216; You need to setup proper package loging to see this!<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ExecutionSuccessfull = False<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0 Else<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 &#8216;Its just a warning.<br \/>\n\u00a0 \u00a0\u00a0\u00a0\u00a0 \u00a0ExecutionSuccessfull = True &#8216; if you want to fail on warning, change this to False<br \/>\n\u00a0\u00a0\u00a0\u00a0\u00a0 End If<br \/>\n\u00a0\u00a0\u00a0 Next oMessage<br \/>\n\u00a0 Next oResult<br \/>\n\u00a0 &#8216; Finished code that creates new partitions<br \/>\n\u00a0 &#8216; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<\/p>\n<p>\u00a0 Done:<br \/>\n\u00a0\u00a0\u00a0 oServer.Disconnect()<\/p>\n<p>\u00a0 If ExecutionSuccessfull Then<br \/>\n\u00a0\u00a0\u00a0 Dts.TaskResult = Dts.Results.Success<br \/>\n\u00a0 Else<br \/>\n\u00a0\u00a0\u00a0 Dts.TaskResult = Dts.Results.Failure<br \/>\n\u00a0 End If<\/p>\n<p>End Sub<br \/>\nEnd Class<\/p><\/blockquote>\n<ul>\n<li>Few notes about last script:\n<ul>\n<li>Trying to run creation of partitions in a single batch in parallel (ExecuteCaptureLog(True, True)) generated error: &#8220;The Alter element at line 9, column 141 (namespace <a href=\"http:\/\/schemas.microsoft.com\/analysisservices\/2003\/engine\">http:\/\/schemas.microsoft.com\/analysisservices\/2003\/engine<\/a>) cannot appear under Envelope\/Body\/Execute\/Command\/Batch\/Parallel.&#8221;<\/li>\n<li>You need to enable proper SSIS package and (!) step logging to see errors\/warnings in the log<\/li>\n<\/ul>\n<\/li>\n<li>Populate table dbo.iwSSASPartitions with the list of partitions you desire<\/li>\n<li>Test run package. Be careful, if you run it with empty table, all partitions will be dropped.<\/li>\n<\/ul>\n<p>Vidas Matelis<\/p>\n<p>Note 2008-July-03, it appears to me that this code might be used by many people. I had multiple requests for actual package and finally <strong>I posted ziped version of package <\/strong><a href=\"http:\/\/www.ssas-info.com\/analysis-services-scripts\/42-scripts\/980-ssis-package-to-drop-and-create-partitions-based-on-data-in-sql-server-table\" target=\"_blank\"><strong>here<\/strong><\/a>.<\/p>\n<p>And thank you very much to everybody who left me (or will leave) comments here about this post. I\u00a0am very happy that you found my code useful!<\/p>\n<p>\u00a0Note 2009-July-05: <a href=\"http:\/\/www.ssas-info.com\/analysis-services-scripts\/1622-script-to-automate-ssas-partition-management-sql-ssis\" target=\"_blank\">Added code that explains how I create SQL Server table and populate partition list here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my past blogs I showed how to use SSIS package to process dimensions, cubes or build aggregates. I am slowly rebuilding my existing packages thanks to points from Darren Gosbell and Jess Orosz. I found that using CaptureXML method is more convenient for me and it is definitely faster.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4,5],"tags":[],"aioseo_notices":[],"_links":{"self":[{"href":"http:\/\/www.ssas-info.com\/VidasMatelisBlog\/wp-json\/wp\/v2\/posts\/13"}],"collection":[{"href":"http:\/\/www.ssas-info.com\/VidasMatelisBlog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.ssas-info.com\/VidasMatelisBlog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.ssas-info.com\/VidasMatelisBlog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.ssas-info.com\/VidasMatelisBlog\/wp-json\/wp\/v2\/comments?post=13"}],"version-history":[{"count":2,"href":"http:\/\/www.ssas-info.com\/VidasMatelisBlog\/wp-json\/wp\/v2\/posts\/13\/revisions"}],"predecessor-version":[{"id":124,"href":"http:\/\/www.ssas-info.com\/VidasMatelisBlog\/wp-json\/wp\/v2\/posts\/13\/revisions\/124"}],"wp:attachment":[{"href":"http:\/\/www.ssas-info.com\/VidasMatelisBlog\/wp-json\/wp\/v2\/media?parent=13"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.ssas-info.com\/VidasMatelisBlog\/wp-json\/wp\/v2\/categories?post=13"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.ssas-info.com\/VidasMatelisBlog\/wp-json\/wp\/v2\/tags?post=13"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}