Как удалить раздел из таблицы? - PullRequest
0 голосов
/ 18 апреля 2019

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

Столбец 'SuperLogId' является столбцом разбиения индекса 'PK__Logs__0E6B88F2'. Столбцы разделов для уникального индекса должны быть подмножеством ключа индекса.

при попытке запустить это:

ALTER TABLE dbo.Logs
ADD PRIMARY KEY CLUSTERED (Id ASC)

Поэтому я попытался следовать этому руководству (https://www.patrickkeisler.com/2013/01/how-to-remove-undo-table-partitioning.html)) и в итоге мне пришлось написать это, чтобы сгенерировать скрипт для объединения всех динамически создаваемых разделов.

DECLARE @partitionsTable dbo.NVarCharCollectionTableType --User-defined table type to hold a collection of NVarChars.

INSERT INTO @partitionsTable
SELECT CONCAT('ALTER PARTITION FUNCTION Logs_SuperLogId_PartitionFunction() MERGE RANGE (', CONVERT(NVARCHAR, [Value]), ')')
FROM SYS.PARTITION_SCHEMES
INNER JOIN SYS.PARTITION_FUNCTIONS ON PARTITION_FUNCTIONS.FUNCTION_ID = PARTITION_SCHEMES.FUNCTION_ID
INNER JOIN SYS.PARTITION_RANGE_VALUES ON PARTITION_RANGE_VALUES.FUNCTION_ID = PARTITION_FUNCTIONS.FUNCTION_ID
WHERE PARTITION_SCHEMES.Name = 'Logs_SuperLogId_PartitionScheme'
AND PARTITION_FUNCTIONS.Name = 'Logs_SuperLogId_PartitionFunction'
ORDER BY [Value] ASC

DECLARE @statement NVARCHAR(MAX)

SELECT @statement =
    CASE
        WHEN @statement IS NULL
        THEN CAST([Text] AS NVARCHAR(MAX))
        ELSE CONCAT(@statement, '; ', [Text])
    END
    FROM @partitionsTable
    ORDER BY [Text] ASC

SELECT @statement

EXECUTE SP_EXECUTESQL @statement

ALTER PARTITION SCHEME Logs_SuperLogId_PartitionScheme NEXT USED [PRIMARY]

Гид предположил, что это как-то поможет, но это не так! Я все еще получаю ту же ошибку при попытке повторно добавить первичный ключ и все еще получаю эти ошибки за попытку отбросить функцию разделения и схему разделения!

DROP PARTITION SCHEME Logs_SuperLogId_PartitionScheme

Схема секционирования "Logs_SuperLogId_PartitionScheme" в настоящее время используется для секционирования одной или нескольких таблиц.

DROP PARTITION FUNCTION CatLogs_CatSessionLogId_PartitionFunction

Функция секционирования 'Logs_SuperLogId_PartitionFunction' используется одной или несколькими схемами секционирования.

Как моя Схема Разделения все еще используется? Почему я не могу просто избавиться от этого, и он больше не используется? Я просто хочу де-секционировать мою таблицу журналов и повторно добавить ее исходный кластеризованный первичный ключ (который я должен был предварительно удалить и заменить некластеризованным первичным ключом, чтобы SuperLogId имел кластеризованный индекс на нем, чтобы его можно было разделить на ).

Обновление:

Мне удалось использовать следующий хак для удаления раздела из моей таблицы, но я все еще не могу удалить схему или функцию раздела.

--HACK: Dummy Index to disassociate the table from the partitioning scheme.
CREATE CLUSTERED INDEX IX_Logs_Id ON dbo.Logs(Id) ON [Primary]

--Now that the table has been disassociated with the partition, this dummy index can be dropped.
DROP INDEX IX_Logs_Id ON dbo.Logs

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

SELECT DISTINCT TABLES.NAME
FROM SYS.PARTITIONS
INNER JOIN SYS.TABLES ON PARTITIONS.OBJECT_ID = TABLES.OBJECT_ID
WHERE PARTITIONS.PARTITION_NUMBER <> 1

Это позволило мне повторно добавить первичный ключ, но я все еще получаю ошибку The partition scheme "Logs_SuperLogId_PartitionScheme" is currently being used... при попытке отбросить схему разделов.

На основе документации Microsoft (https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-partition-scheme-transact-sql?view=sql-server-2017), схема разбиения должна быть сбрасываемой, если на нее нет таблиц или индексов, на которые она ссылается. Поэтому впоследствии я также запустил этот сценарий для проверки индекса с помощью его ...

SELECT DISTINCT indexes.NAME
FROM SYS.PARTITIONS
INNER JOIN SYS.indexes ON indexes.index_id = partitions.index_id
WHERE PARTITIONS.PARTITION_NUMBER <> 1

... И ничего не вернулось! Так что на земле использует мою схему разделов?!

1 Ответ

1 голос
/ 18 апреля 2019

Мне удалось удалить Раздел из его таблицы с помощью следующего кода.

--HACK: Dummy Index to disassociate the table from the partitioning scheme.
CREATE CLUSTERED INDEX IX_Logs_Id ON dbo.Logs(Id) ON [Primary]

--Now that the table has been disassociated with the partition, this dummy index can be dropped.
DROP INDEX IX_Logs_Id ON dbo.Logs

Затем, используя следующий скрипт, обнаружил, что два индекса все еще держатся за схему разбиения.

SELECT SCHEMA_NAME(B.SCHEMA_ID) SCHEMANAME, B.NAME TABLENAME, C.INDEX_ID, C.NAME INDEXNAME, C.TYPE_DESC,
A.PARTITION_NUMBER, D.NAME DATASPACENAME, F.NAME SCHEMADATASPACENAME,
H.VALUE DATARANGEVALUE, A.ROWS,
J.IN_ROW_RESERVED_PAGE_COUNT, J.LOB_RESERVED_PAGE_COUNT,
J.IN_ROW_RESERVED_PAGE_COUNT+J.LOB_RESERVED_PAGE_COUNT TOTALPAGECOUNT,
I.LOCATION
FROM SYS.PARTITIONS A
JOIN SYS.TABLES B ON A.OBJECT_ID = B.OBJECT_ID
JOIN SYS.INDEXES C ON A.OBJECT_ID = C.OBJECT_ID AND A.INDEX_ID = C.INDEX_ID
JOIN SYS.DATA_SPACES D ON C.DATA_SPACE_ID = D.DATA_SPACE_ID
LEFT JOIN SYS.DESTINATION_DATA_SPACES E ON E.PARTITION_SCHEME_ID = D.DATA_SPACE_ID AND A.PARTITION_NUMBER = E.DESTINATION_ID
LEFT JOIN SYS.DATA_SPACES F ON E.DATA_SPACE_ID = F.DATA_SPACE_ID 
LEFT JOIN SYS.PARTITION_SCHEMES G ON D.NAME = G.NAME
LEFT JOIN SYS.PARTITION_RANGE_VALUES H ON G.FUNCTION_ID = H.FUNCTION_ID AND H.BOUNDARY_ID = A.PARTITION_NUMBER
LEFT JOIN (SELECT DISTINCT DATA_SPACE_ID, LEFT(PHYSICAL_NAME, 1) LOCATION FROM SYS.DATABASE_FILES) I ON I.DATA_SPACE_ID = ISNULL(F.DATA_SPACE_ID, D.DATA_SPACE_ID)
LEFT JOIN SYS.DM_DB_PARTITION_STATS J ON J.OBJECT_ID = A.OBJECT_ID AND J.INDEX_ID = A.INDEX_ID AND J.PARTITION_NUMBER = A.PARTITION_NUMBER
ORDER BY 1, 2, 3, A.PARTITION_NUMBER

Все, что мне нужно было сделать, это отбросить два индекса, ссылающихся на Схему Разделения, что позволило мне удалить Схему Разделения, а затем функцию Разделения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...