Вместо экспорта, ручного редактирования и повторного запуска вы можете попробовать выполнить работу непосредственно в базе данных с помощью чего-то вроде:
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
не мешают этому.
Вы захотите провести регрессионное тестирование всего приложения после операции, используете ли вы курсор или методы export + edit + run.
Я использовал этот метод для создания аналогичных обновлений для всей схемы в прошлом. Это что-то вроде хака и кажется довольно уродливым, но иногда это самый простой / быстрый способ.
Значения по умолчанию и другие ограничения также могут быть изменены аналогичным образом, хотя они могут быть только удалены и воссозданы, а не изменены. Что-то типа:
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
функция интерпретации интерпретируется как предыдущий или следующий день в зависимости от времени, оставляя ваши разделы не выровненными с вашими обычными запросами.