вторник, 30 июля 2013 г.
Каникулы группы закончились
суббота, 18 мая 2013 г.
Майская встреча Donetsk Sql Server User Group
Ждем всех на майскую встречу группы. На встрече Сергей расскажет о PowerPivot для SharePoint, я расскажу про SSAS Tabular. Так что Welcome.
Место встречи как обычно г. Донецк, пр.Мира, 8, Компьютерная академия "ШАГ"
понедельник, 25 февраля 2013 г.
Мартовская встреча Donetsk SQL Server User Group
Новая встреча нашей группы. В гости приезжает Костя Хомяков с докладами:
1. Обработка данных в формате CSV используя только возможности SSIS (от простого к сложному)
2. Обработка данных в формате XML используя только возможности SSIS
и я выступлю с докладом:
"Если запрос тормозит, что делать? План выполнения запроса".
Приглашаем всех желающих, только большая просьба зарегистрироваться на встречу в группе на facebook или на портале Ineta, потому что количество мест в аудитории ограничено. Ждем всех на новой встрече группы.
пятница, 8 февраля 2013 г.
Отчет о первой встрече Donetsk Sql Server User Group
- Денис Резник рассказал про Колоночные индексы
- Костя Хомяков сделал доклад: SSIS+DQS на примере импорта данных (Доклад Кости).
среда, 23 января 2013 г.
Первая встреча Donetsk Sql Server User Group
Наконец –то это свершилось. Первая встреча группы. Организовать первую встречу, мне кажется, самое трудное. Она еще конечно не прошла, а только будет. Но чтоб это случилось, пришлось очень хорошо побегать, договорится и т.д.
И так:
вторник, 4 декабря 2012 г.
Donetsk Sql Server User Group
Ну вот могу всех обрадовать, наконец-то, в городе Донецке появилось сообщество по SQL Server. Я являюсь лидером группы и буду стараться ее развивать.
Так что кому интересен Microsoft Sql Server, Integration Services, Analysis Services и все что связано с ними - присоединяйтесь! Минимум раз в месяц планируются доклады. На встречи буду стараться приглашать MVP по Sql Server, которые будут делиться своим опытом, а так же делать свои интересные доклады.
Регистрация и участие в семинарах бесплатное.
Регистрация в сообщество http://ineta.ru/DSSUG. Если вдруг не получается зарегистрироваться – пишите evgen.polonichko”at-commercial”gmail.com
вторник, 20 ноября 2012 г.
Настройка FBA в SharePoint 2010 и раздача прав
В ходе работы над презентацией столкнулся с одной проблемой, необходимо было дать демо-доступ на SharePoint портал, но при этом пользователи, должны иметь минимальные права(то есть фактически просмотр).
Первая мысль, которая пришла, настроить доменного пользователя и все было бы красиво и легко, но …. клиентов может быть много, выдавать один и тот же логин всем, не очень красиво и хотелось бы проанализировать, что смотрят и что им интересно. Поэтому решил установить FBA(Form Based Authentication). Хорошо, если вы настраиваете ферму “с нуля”, тогда можно воспользоваться вот этими ссылочками:
- Блог Дмитрия Плотникова – очень интересный блог о SharePoint на русском языке (ссылка дана сразу на статью о настройке FBA)
- Блог Donal Conlon – конфигурация FBA c помощью IIS 7.0
Но в моем случае, все оказалось сложнее, у меня уже был сайт с настройками, с PerfomancePoint Services, с дашбордами, но он не поддерживал FBA. Поэтому пришлось его конвертировать для поддержки FBA.
Все выполняемые ниже действия вы делаете на свой страх и риск, прежде чем делать, сделайте бэкап.
И так
1 Настраиваем ASP.NET Membership Provider (как настроить смотри в выше приведенных блогах)
2 Необходимо запустить скрипт в powershell (после запуска скрипта откатится к предыдущей системе авторизации невозможно)
$App = get-spwebapplication “URL” – здесь указываем url вашего сайта, который вы хотите перевести на поддержку FBA $app.useclaimsauthentication = “True” $app.Update()
3 После обновления сайта, заходим Центр администрирования->Управления веб-приложениями. Выбираем веб-приложение, на котором крутится ваш сайт и нажимаем поставщики проверки подлинности.
4 В появившемся окне нажимаем на ссылку “по умолчанию” и переходим в "Изменение параметров проверки подлинности”
5 В "Изменение параметров проверки подлинности” разрешаем проверку подлинности на основе форм, прописываем поставщика контроля членства в ASP.NET и имя диспетчера ролей. Сохраняем
6 После чего вам необходимо настроить поставщиков через IIS( блог Donal Conlon начиная с главы Configure Membership Providers for Web App through IIS или попробуйте с помощью утилиты, которую предлагает Дмитрий Плотников). Название поставщиков должно совпадать с названиями, которые вы прописали в предыдущем шаге.
7 Дальше необходимо создать пользователя и группу. Для работы с пользователями, советую установить SharePoint 2010 FBA Pack для сайта, на котором включен FBA.
Теперь создаем группу демо-пользователей с ограниченными правами.
8 Заходим на сайт, для которого настроили FBA, под админом. Переходим меню “Действия сайта” –>” Разрешения сайта”-> “Уровни разрешения”
9 Создаем новый уровень разрешения, я назвал его у себя Демо, добавляем следующие разрешения и сохраняем
10 После этого возвращаемся в “разрешения сайта” создаем группу Демо пользователи и присваиваем ей разрешения демо
11 Все. Мы создали группу, теперь нам достаточно добавлять туда пользователей, которых мы создаем для просмотра демо. И они будут иметь ограниченный доступ. Например на моем сайте, пользователи могут смотреть дашборды и вики-страницы, не могут смотреть элементы списков, документы, загружать их и просматривать их.
четверг, 26 июля 2012 г.
Writeback в SSAS 2012. Маленький пример - план-факт(часть вторая)
В Tabular модели как-то не сложилось у Microsoft c writeback. Writeback mdx в данной модели нет (это подтверждается данной статьей на msdn). Утверждают, что запись в базу доступна через режим DirectQuery + XVelocity, но я этого не смог добиться. Но все по порядку….
Как было в первой части, для проекта берется база AdventureWorks.
Создаем проект
1. Определяем источник данных, добавляем таблицы в модель FactFinance, PlanFinace (таблицы фактов), DimOrganisation, DimDepartamentGroup,DimDate. Создаем связи.
2. Создадим показатели в таблице FactFinance - Amount агрегация Sum и Average, PlanFinance – Amount агрегация Sum.
Модель создали, вроде бы все ок. А вот теперь начинается самое интересное.
В Tabular модели есть 4 режима:
- DirectQuery - запросы отправляются реляционному источнику, кэш при этом не используется.
- DirectQueryWithInMemory – запросы отправляется реляционному источнику, также может использоваться в кэш. Отправка в реляционку первоочередная.
- InMemory – запросы отправляются в кэш
- InMemoryWithDirectQuery – запросы отправляются в кэш, может использоваться реляционка. Отправка в кэш первоочередная(по умолчанию)
Первые два режима работают с DAX запросами и не поддерживают MDX, последних два режима как DAX, так и MDX. А теперь самое интересное - клиент, который может работать с режимами DirectQuery, это Excel 2013. Если у вас ниже офис, то тогда с такими режимами может работать PowerView или SSRS. Ну в принципе это было ожидаемо и я думаю в ближайшем будущем выйду дополнения для 2010 офиса. Также DirectQuery не поддерживают некоторые функции DAX, поэтому прежде чем писать формулы на DAX, включите directquery.
Данные режимы включаются следующим образом:
В свойствах модели DirectQueryMode поставить On, если выбудете работать с режимами DirectQuery или DirectQueryWithInMemory
В свойствах проекта выбираем QueryMode:
И делаем деплой.
Как обычно проект лежит здесь.
Так как же обратная запись – да в принципе никак. Потому что не один клиент ни в каком режиме не позволил сделать изменения в реляционном источнике. Поэтому вопрос, связанный с обратной записью, остается открытым. Я думаю вряд ли 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
- Создаем 3 измерения Dim_Date, Dim_Departament, Dim_Organisation
- Создаем куб и 2 показателя. Один из таблицы FactFinance – Amount, где хранятся наши факты, функцию агрегации используем LastNonEmpty(так как это остатки), второй из таблицы PlanFinance- Amount, функцию агрегации делаем Sum. Название у показателей соответствующие - FactAmount и PlanAmount.
- Включаем writeback. Для этого переходим в раздел Partitions и правой кнопкой мышки нажимаем на партицию PlanFinance, в выпадающем меню выбираем writeback settings
- В появившемся окне вводим название таблицы, куда будут записываться изменения, источник данных и Storage Mode: Molap или Rolap. Я использую Molap.
- Нажимаем Ok и деплоем проект. В итоге в хранилище мы должны получить новую таблицу, в моем случае WriteTable_PlanFinance, в которую теперь будут записываться новые данные, а также логирование, когда была вставлена запись и кем.
И как обычно выкладываю проект, который вы может скачать здесь.
Во второй части, я расскажу реализацию 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.
Первым шагом очищаем предварительную таблицу, после делаем заливку данных из источника в 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.
2 Теперь в исходниках изменим имя у записи Stefanie (это первая запись на рисунке ClientIDSource=1) и изменим код области у Dennis(это запись на рисунке ClientIDSource=2). Запускаем пакет и получаем следующие результаты.
Красным выделено на рисунке строки, которые не являются действующими, в DateTO указана дата до которой эта запись действует, а в флаге isCurrent=0, то есть эта записья уже не является текущей.
И зеленным выделены записи, которые являются действующими на текущей момент. У них указана дата действия с(DateFrom) и флаг iscurrent равен 1. То есть эти записи с новыми атрибутами начинают действовать с даты, указанной в DateFrom.
Плюсы данного метода:
1 Скорость
Минусы
1 Тяжеловатый и не всегда понятный код реализации логики SCD2 с помощью T-SQL
Второй пакет использует компонент из toolbox Slowly Change Dimension.
Всю структуру, которая указана на картинке выше, кроме OLE db source, создаст мастер Slowly Change Dimension. В мастере необходимо указать ключ - bussines key (ключ источника).
И атрибуты, которые будут изменятся
После указываем, что делать с fail записями
и наконец, указываем столбцы, которые отвечают за даты действия.
Также указываем,что делать с столбцом iscurrent
В итоге после нажатия на finish строится набор task-ов.
Плюсы данного метода
1 Понятный мастер, строит логику работы SCD2 сам.
Минус
1 Скорость. При больших объемах данных начинает жутко тормозить.
В своих проектах, я использую первый метод. Потому что у меня редко когда бывает маленький объем данных в справочниках. И если кто заинтересуется, что я изменил после работы с Slowly Change Dimension(второй пакет) ?![]()
Проект SSIS и скрипт по созданию источника данных:
среда, 13 июня 2012 г.
Небольшой перепост о DWH
понедельник, 30 августа 2010 г.
Увольняюсь …..
Да!!! Решил все таки уволится.
Почему?
Есть несколько причин. Ну во-первых не устраивает зп, во вторых наше руководство, которое вдруг стало себя считать самым умным(не ну пусть считают, молодцы, но только не надо показывать это людям, особенно тем, которые знают твой уровень знаний -становится очень смешно), в третьих – надо как-то двигаться, я в принципе закончил свои дела на этой фирме: перевел ее на новый сайт, перевел на новую версию Олап, нашел отличного клиента для олап и т.д. Хватит надо двигаться дальше и развиваться, а то превратишься …….
В общем к новым знаниям, к новому коллективу(хотя старый мне тоже нравился и мне его будет не хватать)
четверг, 26 августа 2010 г.
Работа с партициями в MSAS 2008
Всем привет.
Сегодня хочу описать небольшой скрипт, который я написал для работы с партициями MSAS.
Предыстория
У нас на предприятия есть отчетная система(язык не поворачивается назвать ее аналитической), построенная на основе MSAS. Так вот в чем состояла наша проблема. Вытяжка в таблицу фактов за весь период работы предприятия была, есть и будет очень долго, где-то примерно 10 часов, поэтому чтоб не запускать ее каждый раз решили перейти к партициям в кубе. Каждый год у нас считается что-то типа закрытого периода, обновляются только текущий месяц и предыдущий. Остальные партиции обновляются, только в случае непредвиденных обстоятельств. В MSAS все это выглядит вот так:
Для каждой партиции указан источник:
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: }
Да, я знаю, что код можно было бы упростить. Сделать рефакторинг, но этот будет все потом(нет времени). Сейчас скрипт работает нормально на моей базе.