AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: База знаний и проекты
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 05.01.2007, 02:56   #3  
Torin is offline
Torin
Участник
 
127 / 32 (2) +++
Регистрация: 10.03.2003
Адрес: Odessa, Ukraine
Ага, ну вот.
Сразу, чтобы бы ввести понимание - работает только в Юконе (уровень совместимости неважен), причем Энтерпрайз версии (Или Девелопер - там где партиционирование разрешенно).
Сначала надо создать файловые группы с файлами данных (у меня DATAGROUP1, DATAGROUP2 и т.д.)
Потом функцию и схему
Код:
CREATE PARTITION FUNCTION axDataAreaPF (varchar(3))
AS RANGE LEFT FOR VALUES ('mce', 'mso', 'mea', 'mpc', 'pal', 'pgt', 'psa','pgh');
GO

CREATE PARTITION SCHEME axDataAreaPS
AS PARTITION axDataAreaPF
TO ([DATAGROUP1], [DATAGROUP2], [DATAGROUP3], [DATAGROUP4], [DATAGROUP5], [DATAGROUP6], [DATAGROUP7], [DATAGROUP8], [DATAGROUP9], [DATAGROUP10]);
GO
Где у нас 'mce', 'mso', 'mea', 'mpc', 'pal', 'pgt', 'psa','pgh' - это разные DataArea
По особенностям операторов лучьше почитать в хелпе - есть нюансы с LEFT и лишней группой в схеме.

Далее, само интересное. Этим скриптом я перебираю объекты, проверяю, что они еще не партициионированны и, собственно, do it. Скрипт можно запускать много раз - если ничего не изменилось или не было ошибок, то и делать ничего не будет.
Код:
USE AX64SP3;
SET LOCK_TIMEOUT -1;
GO

DECLARE @table_name varchar(100), @table_id int, @table_partition_type varchar(2), @table_partition_name  varchar(100)
DECLARE @index_name varchar(100), @index_type tinyint, @index_is_unique tinyint, @index_is_primary_key tinyint, @index_is_disabled tinyint, @index_allow_row_locks tinyint, @index_allow_page_locks tinyint, @index_partition_type varchar(2), @index_partition_name  varchar(100)
DECLARE @column_name varchar(100), @column_is_descending_key  tinyint, @column_first tinyint
DECLARE @SQL as nvarchar(4000)
	
DECLARE table_cursor CURSOR FOR
	select DISTINCT o.name, o.object_id, ds.type as type, ISNULL(pf.name, ds.name) as name 
	from 
		sys.partitions AS p
		INNER JOIN sys.indexes AS i ON p.object_id = i.object_id AND p.index_id = i.index_id
		INNER JOIN sys.objects AS o ON o.object_id = i.object_id
		INNER JOIN sys.data_spaces ds ON i.data_space_id=ds.data_space_id
		LEFT JOIN sys.partition_schemes ps ON i.data_space_id=ps.data_space_id
		LEFT JOIN sys.partition_functions pf ON ps.function_id = pf.function_id
	where o.type='U' and i.type=0 and SCHEMA_NAME(o.schema_id) = 'dbo'
	ORDER BY o.name

OPEN table_cursor
FETCH NEXT FROM table_cursor INTO @table_name, @table_id, @table_partition_type, @table_partition_name

WHILE @@FETCH_STATUS = 0
BEGIN
	IF 
		EXISTS(select [name] FROM sys.columns WHERE object_id = @table_id AND UPPER(name) = 'DATAAREAID')
		AND NOT @table_name LIKE 'SYS%'
	BEGIN
		PRINT '--' + @table_name
		IF NOT EXISTS (Select [name] FROM sys.indexes WHERE [type] = 1 AND object_id = @table_id) AND @table_partition_type = 'FG'
		BEGIN
			PRINT '----MOVE TO PARTITION'
			SELECT @SQL = 'CREATE CLUSTERED INDEX tmp_cluster ON ' +@table_name+ '(DATAAREAID) ON axDataAreaPS(DATAAREAID);'
			--PRINT @SQL
			EXEC(@SQL)
			
			SELECT @SQL = 'DROP INDEX tmp_cluster ON ' + @table_name + ';'
			--PRINT @SQL
			EXEC(@SQL)
		END

		Declare index_cursor CURSOR FOR
			Select i.name, i.type, i.is_unique,  i.is_primary_key, i.is_disabled, i.allow_row_locks, i.allow_page_locks, ds.type as type, ISNULL(pf.name, ds.name) as name 
			FROM sys.partitions AS p
				INNER JOIN sys.indexes AS i ON p.object_id = i.object_id AND p.index_id = i.index_id
				INNER JOIN sys.objects AS o ON o.object_id = i.object_id
				INNER JOIN sys.data_spaces ds ON i.data_space_id=ds.data_space_id
				LEFT JOIN sys.partition_schemes ps ON i.data_space_id=ps.data_space_id
				LEFT JOIN sys.partition_functions pf ON ps.function_id = pf.function_id
			WHERE i.object_id = @table_id and i.type>0
			Order by i.type

		OPEN index_cursor
		FETCH NEXT FROM index_cursor INTO @index_name, @index_type, @index_is_unique, @index_is_primary_key, @index_is_disabled, @index_allow_row_locks, @index_allow_page_locks, @index_partition_type, @index_partition_name

		WHILE @@FETCH_STATUS = 0
		BEGIN
			IF @index_partition_type = 'FG'
			BEGIN
				PRINT '----' + @index_name
				SELECT @SQL = 
				CASE WHEN @index_is_primary_key = 1 THEN 
					'ALTER TABLE ' + @table_name + ' DROP CONSTRAINT ' + @index_name +' WITH (ONLINE = OFF); ' 
					+  ' ALTER TABLE ' + @table_name + ' WITH NOCHECK ADD CONSTRAINT ' + @index_name + ' PRIMARY KEY ' +CASE WHEN @index_type = 1 THEN ' CLUSTERED ' ELSE ' ' END 
				ELSE
					'CREATE ' + CASE WHEN @index_type = 1 THEN 'CLUSTERED' WHEN @index_is_unique =1 THEN  'UNIQUE' ELSE '' END +' INDEX ' + @index_name + ' ON '+ @table_name
				END

				Declare column_cursor CURSOR FOR
				Select t3.[name], t2.is_descending_key 
				FROM	sys.indexes t1
						INNER JOIN sys.index_columns t2 ON t1.object_id=t2.object_id AND t1.index_id = t2.index_id
						INNER JOIN sys.columns t3 ON t1.object_id=t3.object_id AND t2.column_id = t3.column_id
				WHERE t1.[name] =@index_name and t1.object_id = @table_id
				Order by t2.index_column_id
				
				SELECT @SQL = @SQL + '('
				SELECT @column_first = 1

				OPEN column_cursor
				FETCH NEXT FROM column_cursor INTO @column_name, @column_is_descending_key
				WHILE @@FETCH_STATUS = 0
				BEGIN
					SELECT @SQL = @SQL + CASE WHEN @column_first=1 THEN '' ELSE ', ' END + @column_name + CASE WHEN @column_is_descending_key = 1 THEN ' DESC' ELSE ' ' END
					SELECT @column_first = 0
					FETCH NEXT FROM column_cursor  INTO @column_name, @column_is_descending_key
				END
				CLOSE column_cursor
				DEALLOCATE column_cursor
				SELECT @SQL = @SQL +
					CASE WHEN @index_is_primary_key = 1 THEN 
						') WITH (FILLFACTOR = 75, ONLINE = OFF) ON axDataAreaPS(DATAAREAID);'
					ELSE
						') WITH (DROP_EXISTING = ON, ONLINE = OFF) ON axDataAreaPS(DATAAREAID);'
					END
				--PRINT @SQL
				EXEC(@SQL)
			END
		FETCH NEXT FROM index_cursor INTO @index_name, @index_type, @index_is_unique, @index_is_primary_key, @index_is_disabled, @index_allow_row_locks, @index_allow_page_locks, @index_partition_type, @index_partition_name
		END
		CLOSE index_cursor
		DEALLOCATE index_cursor
	PRINT 'GO' 	
	END
	FETCH NEXT FROM table_cursor INTO @table_name, @table_id, @table_partition_type, @table_partition_name
END

CLOSE table_cursor
DEALLOCATE table_cursor
Вместо EXEC можно расскомментировать PRINT - тогда результатом работы будет SQL скрипт, который можно разглядывать и выполнять по частям ручками.
AS IS, конечно
За это сообщение автора поблагодарили: George Nordic (1), kashperuk (2), Logger (1), aidsua (1), gl00mie (2), moid (1).
Теги
partition, sql server, партицирование, полезное

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Как вывести из буфера html скрипт на экран? miklenew DAX: Программирование 7 31.03.2010 13:02
Нужен ли кому-нить экспорт-импорт Ax<->1C ax_probe DAX: Администрирование 18 17.03.2005 13:30
Нужен запрет на изменения данных журнала переноса после его распечатки ATimTim DAX: Программирование 4 19.01.2005 12:16
Зачем таблице нужен релэйшн на саму себя? Artild DAX: Программирование 2 21.07.2003 11:52

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 09:17.