четверг, 26 июля 2012 г.

Writeback в SSAS 2012. Маленький пример - план-факт(часть вторая)

 

В Tabular модели как-то не сложилось у Microsoft c writeback.  Writeback mdx в  данной модели нет (это подтверждается данной статьей на msdn). Утверждают, что запись в базу доступна через режим DirectQuery + XVelocity, но я этого не смог добиться. Но все по порядку….

Как было в первой части, для проекта берется база AdventureWorks.

Создаем проект 

image

1. Определяем источник данных, добавляем таблицы в модель FactFinance, PlanFinace (таблицы фактов), DimOrganisation, DimDepartamentGroup,DimDate. Создаем связи.

image

2. Создадим показатели в таблице FactFinance - Amount агрегация  Sum и  Average, PlanFinance – Amount агрегация Sum.

Модель создали, вроде бы все ок. А вот теперь  начинается самое интересное.

В Tabular модели есть 4 режима:

  1. DirectQuery  -  запросы отправляются реляционному источнику, кэш при этом не используется.
  2. DirectQueryWithInMemory – запросы  отправляется реляционному источнику, также может использоваться в кэш. Отправка в реляционку первоочередная.
  3. InMemory – запросы отправляются в кэш
  4. InMemoryWithDirectQuery – запросы отправляются в кэш, может использоваться реляционка. Отправка в кэш первоочередная(по умолчанию)

Первые два режима работают с DAX запросами и не поддерживают MDX,  последних два режима как DAX, так и MDX. А теперь самое интересное  - клиент, который может работать с режимами DirectQuery,  это Excel 2013. Если у вас ниже офис, то тогда   с такими режимами может работать PowerView или SSRS.  Ну в принципе это было ожидаемо и я думаю в ближайшем будущем выйду дополнения для 2010 офиса. Также DirectQuery не поддерживают некоторые функции DAX, поэтому прежде чем писать формулы на DAX, включите directquery.

Данные режимы включаются следующим образом:

В свойствах модели  DirectQueryMode  поставить On, если выбудете работать с режимами DirectQuery  или DirectQueryWithInMemory

image

В свойствах проекта выбираем QueryMode:

image

И делаем деплой.

Как обычно проект лежит здесь.

Так как же обратная запись – да в принципе никак. Потому что не один клиент ни в каком режиме не позволил сделать изменения в реляционном источнике. Поэтому вопрос, связанный с обратной записью, остается открытым. Я думаю вряд ли Microsoft оставит такой продукт без данной функции.

Поживем – увидим.

четверг, 19 июля 2012 г.

Writeback в SSAS 2012. Маленький пример - план-факт(часть первая)


Для чего применяется writeback?  И что такое writeback? 
Кратко, writeback – это обратная запись.  То есть, используя excel 2010(в принципе любой клиент, который поддерживает writeback) вы можете внести изменения в  данные хранилища или измерения. Зачем это?
Данная опция нужна для создания “план-факт” анализа, бюджетирования, корректировки данных в измерениях. Рассмотрим небольшой проект план-факт  и как раз на основе данного проекта я покажу работу с writeback.  Источником данных возьмем AdventureWorks 2012. Плюс сделаем отдельную таблицу для плановых значений (она фактически копия таблицы FactFinance). Код для создания таблицы:
USE [AdventureWorksDW2012]
GO
 
/****** Object:  Table [dbo].[PlanFinance]    Script Date: 17.07.2012 13:10:23 ******/
SET ANSI_NULLS ON
GO
 
SET QUOTED_IDENTIFIER ON
GO
 
CREATE TABLE [dbo].[PlanFinance](
    [FinanceKey] [int] IDENTITY(1,1) NOT NULL,
    [DateKey] [int] NOT NULL,
    [OrganizationKey] [int] NOT NULL,
    [DepartmentGroupKey] [int] NOT NULL,
    [ScenarioKey] [int] NOT NULL,
    [AccountKey] [int] NOT NULL,
    [Amount] [float] NOT NULL,
    [Date] [datetime] NULL
) ON [PRIMARY]
 
GO
 
ALTER TABLE [dbo].[PlanFinance]  WITH CHECK ADD  CONSTRAINT [FK_PlanFinance_DimAccount] FOREIGN KEY([AccountKey])
REFERENCES [dbo].[DimAccount] ([AccountKey])
GO
ALTER TABLE [dbo].[PlanFinance] CHECK CONSTRAINT [FK_PlanFinance_DimAccount]
GO
ALTER TABLE [dbo].[PlanFinance]  WITH CHECK ADD  CONSTRAINT [FK_PlanFinance_DimDate] FOREIGN KEY([DateKey])
REFERENCES [dbo].[DimDate] ([DateKey])
GO
ALTER TABLE [dbo].[PlanFinance] CHECK CONSTRAINT [FK_PlanFinance_DimDate]
GO
ALTER TABLE [dbo].[PlanFinance]  WITH CHECK ADD  CONSTRAINT [FK_PlanFinance_DimDepartmentGroup] FOREIGN KEY([DepartmentGroupKey])
REFERENCES [dbo].[DimDepartmentGroup] ([DepartmentGroupKey])
GO
ALTER TABLE [dbo].[PlanFinance] CHECK CONSTRAINT [FK_PlanFinance_DimDepartmentGroup]
GO
ALTER TABLE [dbo].[PlanFinance]  WITH CHECK ADD  CONSTRAINT [FK_PlanFinance_DimOrganization] FOREIGN KEY([OrganizationKey])
REFERENCES [dbo].[DimOrganization] ([OrganizationKey])
GO
ALTER TABLE [dbo].[PlanFinance] CHECK CONSTRAINT [FK_PlanFinance_DimOrganization]
GO
ALTER TABLE [dbo].[PlanFinance]  WITH CHECK ADD  CONSTRAINT [FK_PlanFinance_DimScenario] FOREIGN KEY([ScenarioKey])
REFERENCES [dbo].[DimScenario] ([ScenarioKey])
GO
ALTER TABLE [dbo].[PlanFinance] CHECK CONSTRAINT [FK_PlanFinance_DimScenario]
GO
 
 

В связи с тем, что для проектов я уже использую SQL 2012, то рассмотрим реализацию writebak, как в многомерной модели, так и в Tabular модели.
1 Многомерная модель
  • Создаем многомерную модель в VS 2010 на основе таблиц FactFinance, PlanFinace (таблицы фактов), DimOrganisation, DimDepartamentGroup,DimDate
image
  • Создаем 3 измерения Dim_Date, Dim_Departament, Dim_Organisation
  • Создаем куб и 2 показателя. Один из таблицы FactFinance – Amount, где хранятся наши факты, функцию агрегации используем LastNonEmpty(так как это остатки), второй из таблицы PlanFinance- Amount, функцию агрегации делаем Sum. Название у показателей соответствующие - FactAmount и PlanAmount.
  • Включаем writeback. Для этого переходим в раздел Partitions  и правой кнопкой мышки нажимаем на партицию PlanFinance, в выпадающем меню выбираем writeback settings
image
  • В  появившемся окне вводим название таблицы, куда будут записываться изменения, источник данных и Storage Mode: Molap или Rolap. Я использую Molap.
image
  • Нажимаем Ok и деплоем проект. В итоге в хранилище мы должны получить новую таблицу, в моем случае WriteTable_PlanFinance, в которую теперь будут записываться  новые данные, а также  логирование, когда была вставлена запись и кем.
Ограничения: К сожалению, есть ограничения, writeback  работает только с показателями, у которых функция агрегации суммирование. Поэтому например  показатель остатки по счетам или на складе, которые  используются с функцией агрегации LastEmpty или LastNonEmpty, необходимо будет реализовывать через фиктивные функции.
И как обычно выкладываю проект, который вы может скачать здесь.
Во второй части, я расскажу реализацию writeback в  Tabular модели SSAS

пятница, 15 июня 2012 г.

SCD2: реализация в SSIS.

 

Кратко,  немного теории:

SCD( slowly change dimension ) называются таблицы измерений, в которых некоторые атрибуты могут изменить свои значения по истечении некоторого периода времени, причем частота таких изменений является небольшой.

Существует три типа таких измерений:

Type 1 -  относятся те измерения, в которых не поддерживается история изменений  атрибута. То есть запись в таблице просто обновляется.

Type 2 - относятся те измерения, в которых поддерживается история изменений атрибута. То есть старая запись помечается как утратившая актуальность, и добавляется новая запись с тем же идентификатором, но уже с обновленными полями. Так же указывается время действия данной записи

Type 3 -  относятся те измерения, в которых поддерживается история изменений атрибута, но в отличие от второго типа, в таблице добавляются новые поля, которые хранят старые значения.

Более подробней по поводу SCD-измерений можно почитать у Ralph Kimball. Информации очень много в сети по данной тематике, так что ищите.

Теперь вернемся к реализации SCD type2   с помощью  ssis .

Создаем таблицу dim_Clients в  MS SQL server 2012

CREATE TABLE [dbo].[dim_Clients](
    [id] [int] IDENTITY(1,1) NOT NULL, --id клиента – уникальная запись, инкрементальная
    [ClientIDSource] [int] NOT NULL,  -- id клиента в источнике
    [NameClients] [varchar](250) NOT NULL, –- имя клиента
    [TypeClients] [int] NULL, –-тип клиента
    [KodObl] [varchar](3) NULL, –-код области
    [DateRegistration] [int] NULL, –- дата регистрации
    [DateFrom] [datetime] NOT NULL, –- дата начала действия даты с
    [DateTo] [datetime] NOT NULL, –- дата окончания действия даты до
    [IsCurrent] [bit] NOT NULL, –- является текущей датой(0 – нет, 1 – да)
 CONSTRAINT [PK_dim_Clients] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO



ALTER TABLE [dbo].[dim_Clients] ADD  CONSTRAINT [DF_dim_Clients_DateFrom]  DEFAULT ('30000101') FOR [DateFrom]
GO
Теперь нам необходима дополнительная  таблица, куда мы будем сливать данные из  исходного источника, а потом обрабатывать и сохранять в таблицу в хранилище.
 
CREATE TABLE [dbo].[dim_ClientsStaging](
    [id] [int] NOT NULL,
    [NameClients] [varchar](250) NOT NULL,
    [TypeClients] [int] NULL,
    [KodObl] [varchar](3) NULL,
    [DateRegistration] [int] NULL
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[dim_ClientsStaging] ADD  CONSTRAINT [DF_dim_ClientsStaging_DateRegistration]  DEFAULT (datediff(day,'',getdate())) FOR [DateRegistration]
GO

Создаем новый проект в SSIS 2012. Добавляем источник откуда мы получаем данные, и источник, куда мы будем заливать данные. После создаем два пакета.

В первом пакете для работы SCD2 используем конструкцию T-SQL merge.

blog1

Первым шагом очищаем предварительную таблицу, после делаем заливку данных из источника в staging таблицу, а потом с помощью  скрипта T-SQL  реализуем логику заполнения для SCD2. Скрипт ниже:

  insert into dbo.dim_Clients
   (  
      [ClientIDSource]
     ,[NameClients]
     ,[TypeClients]
     ,[KodObl]
     ,[DateRegistration]
     ,[DateFrom]
     ,[DateTo]
     ,[IsCurrent]
   )
   select 
      [ClientIDSource]
     ,[NameClients]
     ,[TypeClients]
     ,[KodObl]
     ,[DateRegistration]    
      ,getdate()
      ,'30000101'
      ,1     
      from      
      (
      merge into  dim_Clients  as dst
      using  dbo.dim_ClientsStaging as src
      on
      (
       src.id=dst.[ClientIDSource]
       )
      --new records inserted
      when not matched then 
      insert (
      [ClientIDSource]
     ,[NameClients]
     ,[TypeClients]
     ,[KodObl]
     ,[DateRegistration]    
     ,[DateFrom]
     ,[DateTo]
     ,[IsCurrent]
      )
      values(
      src.id
      ,src.[NameClients]
      ,src.[TypeClients]
      ,src.[KodObl]
      ,src.[DateRegistration]
      , getdate()
      , '30000101'
      ,1
      )
      --existing
     when matched
     and  isCurrent=1
     and
     (src.[NameClients]<>dst.[NameClients]
     or src.[TypeClients]<>dst.[TypeClients]
     or src.[KodObl]<>dst.[KodObl]    
      )
     then update 
     set
     dst.IsCurrent=0,
     dst.DateTo=getdate()
     output 
      src.id as clientidsource
      ,src.[NameClients]
      ,src.[TypeClients]
      ,src.[KodObl]
      ,src.[DateRegistration]
     ,$Action as MergeAction) as  mrg 
      where mrg.MergeAction='update';
   
   

А  теперь тестовый прогон:

1  Первый прогон –заполняются данные расставляются даты и указывается флаг текущая действующая запись isCurrent.

blog2 

 

2 Теперь в исходниках изменим имя у записи Stefanie (это первая запись на рисунке ClientIDSource=1) и изменим код области у Dennis(это  запись на рисунке ClientIDSource=2). Запускаем пакет и получаем следующие результаты.

blog3

Красным выделено на рисунке строки, которые не являются действующими, в DateTO указана дата до которой эта запись действует, а в флаге isCurrent=0, то есть эта записья уже не является текущей.

И зеленным выделены записи, которые  являются действующими на текущей момент. У них указана дата действия с(DateFrom) и флаг iscurrent равен 1. То есть эти записи с новыми атрибутами начинают действовать с даты, указанной в DateFrom.

Плюсы данного метода:

1 Скорость

Минусы

1  Тяжеловатый и не всегда понятный код реализации логики SCD2 с помощью T-SQL

Второй пакет использует компонент из toolbox Slowly Change Dimension.

blog4

Всю структуру, которая указана на картинке выше, кроме OLE db source, создаст  мастер Slowly Change Dimension. В мастере необходимо указать ключ - bussines key (ключ источника).

image

И атрибуты, которые будут изменятся

image

После указываем, что делать с fail записями

image

и наконец, указываем столбцы, которые отвечают за даты действия.

image

Также  указываем,что делать с столбцом iscurrent

image

В итоге  после нажатия на finish строится набор task-ов.

Плюсы данного метода

1 Понятный мастер, строит логику работы SCD2 сам.

Минус

1 Скорость. При больших объемах данных начинает жутко тормозить.

В своих проектах, я  использую первый метод. Потому что у меня редко когда бывает маленький объем данных в справочниках.  И если кто заинтересуется,  что я изменил после  работы с Slowly Change Dimension(второй пакет) ?Улыбка

Проект SSIS и скрипт по созданию источника  данных:

Проект SSIS

Скрипт на создание базы данных с данными

среда, 13 июня 2012 г.

Небольшой перепост о DWH

В данной статье автор рассказывает о метриках хранилища.  Очень хорошая статья кратко, емко и по делу.  Благодаря таким метрикам можем в дальнейшем расчитать различные свойства хранилища(предполагаемый размер хранилища,  средний  рост размера хранилища и т.д.),   для руководства быстро нарисовать инфраструктуру и соответсвенно посчитать   затраты. Спасибо тебе автор odiusage.


понедельник, 30 августа 2010 г.

Увольняюсь …..

 

Да!!! Решил все таки уволится.

Почему?

Есть несколько причин. Ну во-первых не устраивает зп, во вторых наше руководство, которое вдруг стало себя считать самым умным(не ну пусть считают, молодцы, но только не надо показывать это людям,  особенно тем, которые знают твой уровень знаний  -становится очень смешно), в третьих – надо как-то двигаться, я в принципе закончил свои дела  на этой фирме: перевел ее на новый сайт, перевел на новую версию Олап, нашел отличного клиента для олап и т.д. Хватит надо  двигаться дальше и развиваться, а то превратишься …….

В общем к новым знаниям, к новому коллективу(хотя старый мне тоже нравился и мне его будет не хватать)

четверг, 26 августа 2010 г.

Работа с партициями в MSAS 2008

 

Всем привет.

Сегодня хочу описать  небольшой скрипт, который я написал для работы с партициями MSAS.

Предыстория

У нас на предприятия есть отчетная система(язык не поворачивается назвать ее аналитической), построенная на основе MSAS. Так вот  в чем состояла наша проблема. Вытяжка в таблицу фактов за весь период работы предприятия была, есть и будет очень долго, где-то примерно 10 часов, поэтому чтоб не запускать ее каждый раз решили перейти к партициям в кубе. Каждый год у нас считается что-то типа закрытого периода, обновляются только текущий месяц и предыдущий. Остальные партиции  обновляются, только в случае непредвиденных обстоятельств. В MSAS все это выглядит вот так:

as1

Для каждой партиции указан источник:

SELECT *   FROM [dbo].[таблица]   WHERE year(Дата)<=2004

То есть фактически каждая партиция содержит данные за определенный год. Что же касается текущего то, тут чуть другая ситуация.

Для текущего года, на картинки part_2010 источник  другой

SELECT   * FROM  [dbo].[таблица]
  WHERE
(Year(Дата)=2010 ) and   ( (Month(Дата)>=1) and  (Month(Дата)<=6))

а партиция prev  содержит источник за предыдущий месяц и current за текущий.

Такая структура  позволяет обновлять только  2 партиции(текущую и предыдущую) и отказаться от полного процессинга куба.

НО, 1 числа каждого месяца необходимо изменять источник и увеличивать диапазон  в источнике данных   партиции текущего года, как бы наращивать каждый месяц.

Задача

Необходимо написать скрипт, который бы создавал новую партицию и изменял бы в источнике данных запрос

Решение

Решением стал  скрипт, написанный на C# с использованием AMO

   1: public void Main()
   2:        {
   3:            // TODO: Add your code here
   4:            Dts.TaskResult = (int)GetAS();
   5:        }
   6://создание партиции год
   7:        public bool CreatePartitionYear(Cube cubePartition)
   8:        {
   9:            Partition partYear = new Partition("part_" + DateTime.Now.Year.ToString());//создаем объект партиции и назвначаем ему имя
  10:            Microsoft.AnalysisServices.QueryBinding query = new QueryBinding();// создаем объект, отвечающий за источник
  11:            query.DataSourceID = cubePartition.DataSource.ID;//указываем  id источника
  12:            partYear.StorageMode = StorageMode.Molap;//указываем тип партции
  13:            query.QueryDefinition = "SELECT  * FROM [dbo].[таблица] WHERE (Year(Дата)=" + DateTime.Now.Year.ToString() + " ) and   (Month(Дата)=1) ";//указываем собственно запрос
  14:            partYear.Source = query;// присваевается объект источника  партиции
  15:            try
  16:            {
  17:                cubePartition.MeasureGroups[0].Partitions.Add(partYear);//добавляем партицию в куб
  18:                partYear.Update();//отправляем новое определение объекта на сервер
  19:                partYear.Update(UpdateOptions.AlterDependents);// на всякий случай
  20:                cubePartition.MeasureGroups[0].Update(UpdateOptions.AlterDependents);//обновляем структуру секций
  21:                cubePartition.Update();//обновляем  структуру куба
  22:                cubePartition.Refresh();//делаем синхронизацию объектов  Amo и as
  23:                cubePartition.MeasureGroups[0].Refresh();//делаем синхронизацию объектов  Amo и as
  24:            }
  25:            catch (Exception exp)
  26:            {
  27:                return false;
  28:            }
  30:            Partition partNew;
  32:            partNew = cubePartition.MeasureGroups[0].Partitions.FindByName("prev");// ищем  партицию prev
  33:            try
  34:            {
  35:                if (partNew != null) partNew.Drop();//если существуе, удаляем
  36:            }
  37:            catch (Exception exp)
  38:            {
  40:            }
  41:            partNew = cubePartition.MeasureGroups[0].Partitions.Add("prev");// добавляем партицию
  42:            partNew.StorageMode = StorageMode.Molap;// указываем тип партции
  43: /создаем запрос для источника партиции
  44:            Microsoft.AnalysisServices.QueryBinding queryPrev = new QueryBinding();
  45:            queryPrev.QueryDefinition = "SELECT  * FROM [dbo].[Таблица] WHERE (Year(Дата)=" + DateTime.Now.Year.ToString() + " ) and   (Month(Дата)=" + (DateTime.Now.Month - 1).ToString() + ") ";
  46:            queryPrev.DataSourceID = cubePartition.DataSource.ID;
  47:            partNew.Source = queryPrev;
  49:            partNew.Update();//обновляем структур
  50:            cubePartition.MeasureGroups[0].Update(UpdateOptions.AlterDependents);//обновляем структуру секций
  51:            cubePartition.Update();//обновляем структуру куба
  52:            cubePartition.Refresh();//синхронизируем объекты
  53:            cubePartition.MeasureGroups[0].Refresh();//синхронизируем объекты         
  54:            return true;
  55:        }
  56: /создание партиции месяц
  57:        public bool CreatePartitionMonth(Cube cubePartition)
  58:        {
  59:            Partition part = cubePartition.MeasureGroups[0].Partitions.FindByName("part_" + DateTime.Now.Year.ToString());//ищем партцию текущего года
  60:            if (part != null)
  61:             {
  62:                        Partition partPrev = cubePartition.MeasureGroups[0].Partitions.FindByName("prev");//ищем партицию prev
  63:                        List<Partition> lspPart = new List<Partition>();//список партиций
  64:                        Microsoft.AnalysisServices.QueryBinding query = new QueryBinding();//объект  источник для партиции года
  65:                        query.DataSourceID = cubePartition.DataSource.ID;
  66:                        if ((DateTime.Now.Month == 1))//проверка на месяц
  67:                        {
  68: //Сделано для того, чтобы не возникала ситуация 1-2(текущий месяц январь(01, то есть 1), для вычисления  месяца, который был 2 месяца назад, то есть 1-2=-1 и получаем exception. Да можно было бы от этого избавится и использовать функции месяца и вычислять минус 62 дня, но так наглядней и понятней
  69:                            query.QueryDefinition = "SELECT  * FROM [dbo].[таблица] WHERE (Year(Дата)=" + (DateTime.Now.Year-1).ToString() + " ) and   (Month(Дата)=11) ";
  70:  
  71:                        }
  72:                        else
  73:                        {
  74:                            if ((DateTime.Now.Month == 2))//проверка на второй месяц. 
  75:                            {
  76:                                query.QueryDefinition = "SELECT  * FROM [dbo].[таблица] WHERE (Year(Дата)=" + (DateTime.Now.Year - 1).ToString() + " ) and   (Month(Дата)=12) ";
  77:                            }
  78:                            else
  79:                            {
  80:                                query.QueryDefinition = "SELECT  * FROM [dbo].[таблица] WHERE (Year(Дата)=" +
  81:                                    DateTime.Now.Year.ToString() + " ) and   ((Month(Дата)>=1) and (Month(Дата)<=" + (DateTime.Now.Month - 2).ToString() + ")) ";
  82:                            }
  83:                        }
  84:                        part.Source = query;
  86:                 lspPart.Add(partPrev);
  88:                        try
  89:                        {
  90:                            part.Merge(lspPart);//сливаем партиции
  91:                            part.Update(UpdateOptions.AlterDependents);//обновляем структуру секции год
  92:                            cubePartition.MeasureGroups[0].Update(UpdateOptions.AlterDependents);//обновляем структуру секций
  93:                            cubePartition.Update();//обновляем структур куба
  94:                            cubePartition.Refresh();//синхронизация
  95:                            cubePartition.MeasureGroups[0].Refresh();//синхронизация
  97:                        }
  98:                        catch(Exception exp)
  99:                        {
 100:                            string message = exp.Message;
 101:                            return false;
 102:                        }
 104:                        try
 105:                        {
 106:              //здесь создаем партицию prev             
 107:                             Partition partNew;
 108:                            
 109:                            partNew =cubePartition.MeasureGroups[0].Partitions.FindByName("prev");
 110:                            try
 111:                            {
 112:                                if (partNew != null) partNew.Drop();
 113:                            }
 114:                            catch (Exception exp)
 115:                            {
 116:                                
 117:                            }
 118:                            partNew = cubePartition.MeasureGroups[0].Partitions.Add("prev");
 119:                            partNew.StorageMode = StorageMode.Molap;
 120:                            
 121:                            Microsoft.AnalysisServices.QueryBinding queryPrev = new QueryBinding();
 122:                            queryPrev.QueryDefinition = "SELECT  * FROM [dbo].[таблица] WHERE (Year(Дата)=" + DateTime.Now.Year.ToString() + " ) and   (Month(Дата)=" + (DateTime.Now.Month - 1).ToString() + ") ";
 123:                            queryPrev.DataSourceID = cubePartition.DataSource.ID;
 124:                            partNew.Source = queryPrev;
 126:                            partNew.Update();
 127:                            cubePartition.MeasureGroups[0].Update(UpdateOptions.AlterDependents);
 128:                            cubePartition.Update();
 129:                            cubePartition.Refresh();
 130:                            cubePartition.MeasureGroups[0].Refresh();
 132:                        }
 133:                        catch (Exception exp)
 134:                        {
 135:                            string message = exp.Message;
 136:                            return false;
 137:                        }
 139:             }
 140:             return true;
 141:        }
 142:  
 143:/ /процессинг партиций
 144:        public bool ProccesPartition(Cube cubePartition)
 145:        {
 146:            Partition partPrev = cubePartition.MeasureGroups[0].Partitions.FindByName("prev");//ищем партицию
 147:            if (partPrev != null)
 148:            {
 149:                partPrev.Process(ProcessType.ProcessFull);//делаем полный процессинг
 150:            }
 151:            else
 152:            {
 153:                return false;
 154:            }
 156:            Partition parCurrent = cubePartition.MeasureGroups[0].Partitions.FindByName("current");//ищем партицию
 157:            if (parCurrent != null)
 158:            {
 159:                parCurrent.Process(ProcessType.ProcessFull);//полный процессинг
 160:  
 161:            }
 162:            else
 163:            {
 164:                return false;
 165:            }
 167:            return true;
 169:        }
 170:  
 172:        public int GetAS()
 173:        {
 174:            using(Server srv=new Server())
 175:            {
 176:                srv.Connect("localhost");//коннектимся к серверу
 177:                Database db = srv.Databases.GetByName("ИмяБазы");//конектимся к базе
 178:                if (db != null)
 179:                {
 180:                    Cube cubeOverturn = db.Cubes.GetByName("ИмяКубика");//ищем кубик
 181:                    if (cubeOverturn != null)
 182:                    {
 183:                        DateTime dt = DateTime.Now;//определяем текущее время
 184:                        if (dt.Day == 1)
 185:                        {
 186:                            if (dt.Month == 3)
 187:                            {
 188:                                if (!CreatePartitionYear(cubeOverturn))//создаем партцию года
 189:                                {
 190:                                    srv.Disconnect();
 191:                                    return (int)ScriptResults.Failure;
 192:                                }
 193:                                else
 194:                                {
 195:                                    ProccesPartition(cubeOverturn);//процессим партиции
 196:                                }
 197:                            }
 198:                            else
 199:                            {
 200:                                if (!CreatePartitionMonth(cubeOverturn))//создаем партиции месяца
 201:                                {
 202: /произошла ошибка
 203:                                    srv.Disconnect();//разрываем связь
 204:                                    return (int)ScriptResults.Failure;//возвращаем fail
 205:                                }
 206:                                else
 207:                                {
 208:                                    ProccesPartition(cubeOverturn);//процессим
 209:                                }
 210:                            }
 211:                        }
 212:                        else
 213:                        {
 214:                            if (!ProccesPartition(cubeOverturn))//просто процессим
 215:                            {
 216:                                srv.Disconnect();
 217:                                return (int)ScriptResults.Failure;
 218:                            }
 220:                        }
 221:                    }
 222:                    else
 223:                    {
 224:                        srv.Disconnect();
 225:                        return (int)ScriptResults.Failure;
 226:                    }
 228:                }
 229:                else
 230:                {
 231:                    srv.Disconnect();
 232:                    return (int)ScriptResults.Failure;
 233:                }
 234:                srv.Disconnect();
 235:            }
 238:            return (int)ScriptResults.Success;
 239:        }
 242:    }

Да, я знаю, что код можно было бы упростить. Сделать рефакторинг, но  этот будет все потом(нет времени). Сейчас скрипт работает нормально на  моей базе.