Замість того, щоб експортувати, вручну редагувати та повторно використовувати, ви можете спробувати виконати роботу безпосередньо в базі даних із чимось на зразок:
DECLARE C CURSOR FOR
SELECT sm.definition, so.type
FROM sys.objects so
JOIN sys.all_sql_modules sm ON sm.object_id = so.object_id
WHERE so.type IN ('P', 'V')
ORDER BY so.name
DECLARE @SQL NVARCHAR(MAX), @ojtype NVARCHAR(MAX)
OPEN C
FETCH NEXT FROM C INTO @SQL, @ojtype
WHILE @@FETCH_STATUS = 0 BEGIN
IF @objtype = 'P' SET @SQL = REPLACE(@SQL, 'CREATE PROCEDURE', 'ALTER PROCEDURE')
IF @objtype = 'V' SET @SQL = REPLACE(@SQL, 'CREATE VIEW' , 'ALTER VIEW' )
SET @SQL = REPLACE(@SQL, 'GETDATE()', '[dbo].[getlocaldate]()')
--PRINT @SQL
EXEC (@SQL)
FETCH NEXT FROM C INTO @SQL, @ojtype
END
CLOSE C
DEALLOCATE C
звичайно, розширюючи його і на функції, тригери тощо.
Є кілька застережень:
Можливо, вам знадобиться бути трохи яскравішим і мати справу з різними / додатковими пробілами між CREATE
та PROCEDURE
/ VIEW
/ <other>
. Замість того, REPLACE
щоб ви могли замість цього залишити CREATE
місце на місці та виконати DROP
перше виконання, але це ризикує залишити sys.depends
та друзів позабитий там, де ALTER
це не можливо, також, якщо ALTER
ви не зможете, принаймні, наявний об’єкт все ще знаходиться на місці, де з DROP
+ CREATE
ви можете ні.
Якщо в коді є якісь "розумні" запахи, як зміна власної схеми за допомогою спеціального TSQL, вам потрібно переконатися, що пошук і заміна на CREATE
-> ALTER
не перешкоджають цьому.
Вам потрібно буде перевірити регресію всієї програми (програм) після операції, незалежно від того, використовуєте ви курсор або експортуєте + редагувати + запускати методи.
У минулому я використовував цей метод, щоб робити подібні оновлення для всіх схем. Це трохи хак, і відчуває себе досить потворно, але іноді це найпростіший / швидкий спосіб.
Значення за замовчуванням та інші обмеження також можуть бути змінені аналогічно, хоча вони можуть бути виключені та відтворені, а не змінені. Щось на зразок:
DECLARE C CURSOR FOR
SELECT AlterDefaultSQL = 'ALTER TABLE [' +st.name+ '] DROP CONSTRAINT [' + si.name + '];'
+ CHAR(10)
+ 'ALTER TABLE [' +st.name+ '] ADD CONSTRAINT [' + si.name + '] DEFAULT '+REPLACE(si.definition, 'GETDATE()', '[dbo].[getlocaldate]()')+' FOR '+sc.name+';'
FROM sys.tables st
JOIN sys.default_constraints si ON si.parent_object_id = st.object_id
JOIN sys.columns sc ON sc.default_object_id = si.object_id
DECLARE @SQL NVARCHAR(MAX)
OPEN C
FETCH NEXT FROM C INTO @SQL
WHILE @@FETCH_STATUS = 0 BEGIN
--PRINT @SQL
EXEC (@SQL)
FETCH NEXT FROM C INTO @SQL
END
CLOSE C
DEALLOCATE C
Ще кілька забав, з якими вам може знадобитися протистояти: якщо ви розбиваєтеся за часом, то ці частини також можуть знадобитися зміни. Хоча час розбиття детальніше, а потім за днем, це рідкість, у вас можуть виникнути проблеми, коли DATETIME
функція секціонування інтерпретується як попередній або наступний день залежно від timezine, залишаючи ваші розділи не узгодженими із вашими звичайними запитами.