Страница 1 из 1

MS SQL очистка битых ATTRVAL

Добавлено: 26 сен 2023, 10:09
KVS
Недавно понадобилось быстро удалить из ATTRVAL записи, для которых не существует записи в родительской таблице.
Оставлю тут, мб кому-нибудь понадобится.

Код: Выделить всё

SET NOCOUNT ON

CREATE TABLE #XX$LOCKS(TABLENREC BINARY(8));
--Удаляем все значения атрибутов, для которых нет наименования атрибута
DELETE FROM T$ATTRVAL WHERE NOT EXISTS(SELECT 1 FROM T$ATTRNAM T1 WHERE T1.F$NREC = F$CATTRNAM)

DECLARE @Q VARCHAR(MAX);
--Формируем запросы на удаление данных
DECLARE CUR CURSOR FOR SELECT FORMATMESSAGE('
                                DELETE FROM T$ATTRVAL 
                                WHERE F$WTABLE = %s 
                                AND NOT EXISTS (SELECT 1 FROM T$%s WHERE F$%s = F$CREC);'
                              , CAST(XF$CODE AS VARCHAR(20))
                              , XF$NAME
                              , XE$NAME) 
                       FROM X$FILES
                       JOIN X$INDEXES ON XI$FILECODE = XF$CODE AND XI$FLAGS&512 <> 0 --Это суррогатный ключ
                       JOIN X$FIELDS  ON XE$FILECODE = XF$CODE AND XE$CODE = XI$FIELDCODE
                       WHERE XF$CODE >= 900
                       ORDER BY XF$CODE ASC

OPEN CUR;

--Выполняем подготовленные запросы
FETCH NEXT FROM CUR INTO @Q;
WHILE @@FETCH_STATUS = 0
BEGIN 
  EXECUTE(@Q)
  PRINT CAST(@@ROWCOUNT AS VARCHAR(20)) + '****' + @Q
  FETCH NEXT FROM CUR INTO @Q;
END

CLOSE CUR;
DEALLOCATE CUR;

DELETE FROM XX$Memo WHERE M#Code = 1006 AND NOT EXISTS(SELECT 1 FROM T$ATTRVAL WHERE F$NREC = M#NRec)
DROP TABLE #XX$LOCKS;