Зміна користувацьких типів таблиць у SQL Server


Відповіді:


69

Наскільки мені відомо, неможливо змінити / змінити тип таблиці. Ви можете створити тип з іншим ім'ям, а потім скинути старий тип і змінити його на нове ім'я

Подяки jkrajes

Відповідно до msdn , це як "Визначення користувачем визначення типу таблиці не може бути змінено після його створення".


2
Я використовую серію згенерованих сценаріїв падіння / створення всіх об’єктів залежно від визначеного користувачем типу та самого визначеного користувачем типу.
Ронні Овербі

6
Як у підсумку отримати 20 000+ сценаріїв рядків у sql? скидання / створення всіх залежностей типів таблиць, які потрібно змінити. : P
Spacemonkey

14
Це жахливо (Microsoft), тепер мені доводиться змінювати ВСІ, коли я вношу зміни до цих таблиць, потім видаляти, відтворювати і повертатися назад та оновлювати БУДЬ-ЯКІ посилання на них. Погано продуманий .. Я знаю, що це роздуми, але про що вони думали ??
schmoopy

1
Також, схоже, вам навіть не дозволено змінювати власника визначеного користувачем типу таблиці. Видалення типу таблиці та створення його заново з новим іменем власника здається єдиним способом змінити ім’я власника на випадок, якщо вам потрібно це змінити. sp_changeobjectowner не працює з типами таблиць, що визначаються користувачем ...
Джефф,

38

Це свого роду хакерство, але, здається, працює. Нижче наведені кроки та приклад зміни типу таблиці. Одне зауваження - модуль sp_refreshsqlмодулюватиме, якщо зміна, яку ви внесли до типу таблиці, є невід’ємною зміною цього об’єкта, як правило, процедурою.

  1. Використовуйте sp_renameдля перейменування типу таблиці, я зазвичай просто додаю z на початок імені.
  2. Створіть новий тип таблиці з оригінальною назвою та будь-якими змінами, які потрібно внести до типу таблиці.
  3. Пройдіть кожну залежність і запустіть sp_refreshsqlmoduleїї.
  4. Відкиньте перейменований тип таблиці.

EXEC sys.sp_rename 'dbo.MyTableType', 'zMyTableType';
GO
CREATE TYPE dbo.MyTableType AS TABLE(
    Id INT NOT NULL,
    Name VARCHAR(255) NOT NULL
);
GO
DECLARE @Name NVARCHAR(776);

DECLARE REF_CURSOR CURSOR FOR
SELECT referencing_schema_name + '.' + referencing_entity_name
FROM sys.dm_sql_referencing_entities('dbo.MyTableType', 'TYPE');

OPEN REF_CURSOR;

FETCH NEXT FROM REF_CURSOR INTO @Name;
WHILE (@@FETCH_STATUS = 0)
BEGIN
    EXEC sys.sp_refreshsqlmodule @name = @Name;
    FETCH NEXT FROM REF_CURSOR INTO @Name;
END;

CLOSE REF_CURSOR;
DEALLOCATE REF_CURSOR;
GO
DROP TYPE dbo.zMyTableType;
GO

УВАГА:

Це може бути руйнівним для вашої бази даних, тому вам спочатку потрібно перевірити це на середовищі розробки.


зауваження щодо sp_refreshsqlmodule за посиланням MSDN: msdn.microsoft.com/en-us/library/bb326754.aspx є досить загрозливим. Але чи цей SP також оновлює текст об'єктів, на які посилаються, або просто оновлює там скомпільовану форму. Я маю на увазі, якщо я запущу SP_HELPTEXT на одному із моїх посилань на SP, тоді я отримаю там нову назву типу чи ні?
йог

Це не змінить тип таблиці у збереженій процедурі на тип таблиці z. Все, що він робить, оновлює схему як є, але фіксує посилання на тип таблиці. Якщо sp_refreshsqlmodleпісля відтворення типу таблиці ви не запустите процес зберігання в магазині, збережений процес не вдасться сказати, що тип таблиці змінився. Я рекомендую запустити це на розробницькій версії вашої БД перед запуском у виробничій роботі.
Норландо

1
Ця відповідь для мене не спрацювала. Як тільки sp_rename виконується, тип параметра на SP оновлюється для посилання на нову UDTT. Тоді згодом перейменований UDTT не можна скидати. sp_rename застосовує залежності. Ця відповідь передбачає, що sp_rename не буде оновлювати тип параметра при посиланні на SP.
муртазат

sp_renameна типі даних, який визначає користувач, викиньте мені помилку: Either the parameter @objname is ambiguous or the claimed @objtype ((null)) is wrong.що може бути не так?
Muflix

1
@Muflix, можливо, вам доведеться передати такий тип об'єкта EXEC sys.sp_rename 'dbo.MyTableType', 'zMyTableType', 'OBJECT';. Також переконайтеся, що ви включаєте схему для першого параметра, а не для другого.
norlando

15

Ось прості кроки, які мінімізують нудьгу і не вимагають схильних до помилок напівавтоматизованих сценаріїв або дорогих інструментів.

Майте на увазі, що ви можете генерувати оператори DROP / CREATE для декількох об’єктів з вікна Подробиці провідника об’єктів (при цьому генеруються сценарії DROP та CREATE, що полегшує введення логіки між діями Drop і Create):

Перетягніть і створіть до

  1. Створіть резервну копію бази даних, якщо щось піде не так!
  2. Автоматично генерувати оператори DROP / CREATE для всіх залежностей (або генерувати для всіх об'єктів "Програмованість", щоб усунути нудьгу пошуку залежностей).
  3. Між операторами DROP і CREATE [залежності] (після DROP, перед усіма CREATE) вставте згенеровані оператори DROP / CREATE [тип таблиці], вносячи необхідні зміни за допомогою CREATE TYPE.
  4. Запустіть сценарій, який скидає всі залежності / UDTT, а потім відтворює [UDTT із змінами] / залежності.

Якщо у вас є менші проекти, де може мати сенс змінити архітектуру інфраструктури, розгляньте можливість усунення визначених користувачем типів таблиць. Entity Framework та подібні інструменти дозволяють перенести більшість, якщо не всю, логіки даних до бази коду, де її простіше підтримувати.


1
Я скористався вашою порадою і розглянув міграцію сотень тисяч рядків коду для використання Entity Framework, щоб нам уникнути необхідності скидати та відтворювати визначений користувачем тип таблиці. Але через секунду я вирішив, що скидання та відтворення типу таблиці на сьогоднішній день є простішим шляхом.
PapillonUK

1
@PapillonUK, я з тобою. У мене є більший проект, тому я все ще приймаю те саме рішення, що і ви (а метод, наведений вище, настільки швидкий, що я, ймовірно, продовжуватиму його в найближчому майбутньому). Я згадав про відхід від UDTT для тих, хто має менші проекти, де, можливо, має сенс змінити архітектуру зараз, щоб спростити майбутні зміни, тому я відповідно оновив свою відповідь. Дякую.
легкий мотив

9

Якщо ви можете використовувати проект бази даних у Visual Studio, ви можете внести зміни в проект і скористатися схемою порівняння для синхронізації змін у вашій базі даних.

Таким чином, скидання та відтворення залежних об'єктів обробляється сценарієм змін.


Я знайшов цю відповідь корисною разом із відповіддю
BioEcoSS

8

Саймон Зейнстра знайшов рішення!

Але я використовував Visual Studio community 2015, і мені навіть не потрібно було використовувати порівняння схем.

Використовуючи SQL Server Object Explorer, я знайшов свій тип таблиці, визначений користувачем, у БД. Я клацнув правою кнопкою миші на типі таблиці та вибрав. Це відкрило вкладку коду в IDE із видимим та редагованим кодом TSQL . Я просто змінив визначення (у моєму випадку просто збільшив розмір поля nvarchar) і натиснув кнопку Оновити базу даних у верхньому лівому куті вкладки.

Гей, Престо! - швидка перевірка в SSMS, і визначення udtt було змінено.

Блискуче - дякую Саймоне.


1
Це, мабуть, краще підходить як коментар до відповіді, а не як відповідь сам по собі.
Філ Купер

TBH Я знайшов це досить корисним, був для мене простим шляхом вирішення цієї проблеми, пояснюючи, як це зробити для таких людей, як я, які не надто знайомі з проектами баз даних у Visual Studio.
Стів Кеннерд

Я також знайшов цю відповідь корисною
Падміка

Дякуємо, що поділились цим = D
Ayorus

4

Вам слід скинути старий тип таблиці та створити новий. Однак, якщо він має якісь залежності (будь-які збережені процедури, що використовують його), ви не зможете його скинути. Я опублікував чергову відповідь про те, як автоматизувати процес тимчасового скидання всіх збережених процедур, модифікації таблиці таблиць, а потім відновлення збережених процедур.


Хіба це не те, що він мав би залежності, інакше для чого б ви його створили для початку?
LarryBud

@LarryBud - Один простий приклад може бути, якщо хтось просто створив його і ще не мав можливості використовувати його в будь-якій збереженій процедурі і т. Д.
BornToCode

3

Ви не можете ЗМІНИТИ / ЗМІНИТИ ТИП. Вам потрібно скинути існуючий і заново створити його з правильним ім’ям / типом даних або додати новий стовпець / и

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.