SQL Server 2012 - невозможно удалить пользовательский (табличный) тип, когда нет активных зависимостей - PullRequest
0 голосов
/ 08 мая 2018

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

Это сценарий:

  1. Переименуйте тип с T_MyType на T_MyType_1,
  2. Попросите Management Studio создать сценарий создания для типа T_MyType_1,
  3. Отредактируйте скрипт, удалите «_1» из имени типа и увеличьте размер одного поля, затем запустите скрипт,
  4. Запустить процедуру, которая вызвала проблему усечения (длина столбца) и получила успешный результат (без усечения и сообщений об ошибках),
  5. Попытка удалить тип T_MyType_1 и ошибка, указывающая, что тип используется процедурой ABC,
  6. Поиск T_MyType_1 в теле процедуры ABC и строка не найдена .

Итак, я застрял с определенным типом, который необходимо удалить.

Редактировать

Я считаю, что этот вопрос отличается от предложенных дубликатов.

Ответы [ 2 ]

0 голосов
/ 09 мая 2018

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

CREATE TYPE BadUdt FROM NVARCHAR(10);
GO
CREATE PROCEDURE AreUdtsBadThough(@T BadUdt) AS BEGIN
    RETURN;
END;
GO
EXEC sp_rename 'BadUdt', 'GoodUdt';
GO
CREATE TYPE BadUdt FROM NVARCHAR(20);
GO
EXEC AreUdtsBadThough NULL

Сообщение 496, Уровень 16, Состояние 1, ПроцедураAreUdtsBadThough, Строка 6 [Batch Start Line 16] Параметр "@T" отличается от типа, с которым он был создан.Удалите и заново создайте модуль, используя двухэлементное имя для типа, или используйте sp_refreshsqlmodule для обновления метаданных его параметров.

Несмотря на изменение имени, параметр AreUdtsBadThough по-прежнему связан со старымвведите по идентификатору, поэтому вы не можете удалить это:

SELECT p.[name], t.[name]
FROM sys.parameters p
JOIN sys.types t ON p.user_type_id = t.user_type_id
WHERE [object_id] = OBJECT_ID('AreUdtsBadThough')
+------+---------+
| name |  name   |
+------+---------+
| @T   | GoodUdt |
+------+---------+

Ошибка полезно описывает общее решение проблем с зависимостями: invoke sp_refreshsqlmodule, что вызываетхранимая процедура (или функция, или триггер, или представление) для эффективной перекомпиляции и обновления зависимостей:

EXEC sp_refreshsqlmodule 'AreUdtsBadThough'

SELECT p.[name], t.[name]
FROM sys.parameters p
JOIN sys.types t ON p.user_type_id = t.user_type_id
WHERE [object_id] = OBJECT_ID('AreUdtsBadThough')
+------+--------+
| name |  name  |
+------+--------+
| @T   | BadUdt |
+------+--------+

А теперь GoodUdt больше не имеет зависимостей и может быть отброшена.

Проблема не всегда корректно обновляемых зависимостей (которая не ограничивается переименованием) побудила некоторых людей придумать более постоянные решения.Аарон Бертран (Aaron Bertrand) написал статью об автоматизации обновлений зависимостей для SQL Server 2008 (которая должна работать в более поздних выпусках, даже если она может выполнять больше работы, чем необходимо) из-за улучшенных проверок зависимостей.

0 голосов
/ 08 мая 2018

Я бы никогда не переименовал объект. Как правило, это не рекомендуется, и я знаю, что это может вызвать проблемы. Скорее всего, это суть вашей проблемы, и я подозреваю, что за всем этим скрыты некоторые карты.

В целом: если ALTER недоступен, переименование не будет полезным.

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

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