En lugar de exportar, editar manualmente y volver a ejecutar, puede intentar hacer el trabajo directamente en la base de datos con algo como:
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
por supuesto, extenderlo para tratar funciones, disparadores, etc.
Hay algunas advertencias:
Es posible que deba ser un poco más brillante y lidiar con espacios en blanco diferentes / adicionales entre CREATE
y PROCEDURE
/ VIEW
/ <other>
. En lugar de REPLACE
eso, es posible que prefiera dejar el CREATE
lugar en su lugar y ejecutar DROP
primero, pero esto corre el riesgo de dejar a sus sys.depends
amigos fuera de lugar donde ALTER
no pueda, también si ALTER
falla, al menos tiene el objeto existente todavía en su lugar donde con DROP
+ CREATE
puede no.
Si su código tiene algún olor "inteligente", como modificar su propio esquema con TSQL ad-hoc, entonces deberá asegurarse de que la búsqueda y el reemplazo de CREATE
-> ALTER
no interfieran con eso.
Querrá probar la regresión de la (s) aplicación (es) completa (s) después de la operación, ya sea que use el cursor o los métodos exportar + editar + ejecutar.
He usado este método para hacer actualizaciones similares en todo el esquema en el pasado. Es un truco y se siente bastante feo, pero a veces es la forma más fácil / rápida.
Los valores predeterminados y otras restricciones también se pueden modificar de manera similar, aunque solo se pueden eliminar y recrear en lugar de modificar. Algo como:
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
Un poco más de diversión con la que puede que tenga que lidiar: si está haciendo particiones por tiempo, entonces esas partes también pueden necesitar modificaciones. Si bien la partición a tiempo de forma más granular que por día es poco frecuente, podría tener problemas en DATETIME
los que la función de partición interpreta los s como el día anterior o siguiente, dependiendo de la zona horaria, dejando sus particiones sin alinear con sus consultas habituales.