El concepto básico es realmente bastante simple: genera un script desde sys.objects
y sys.schemas
que construye ALTER SCHEMA TRANSFER
declaraciones. Entonces, por ejemplo, tiene tres objetos en el dbo
esquema y desea moverlos todos al blat
esquema:
Table: dbo.foo
Table: dbo.bar
View: dbo.vFooBar
El siguiente código:
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += N'
ALTER SCHEMA blat TRANSFER dbo.' + QUOTENAME(o.name) + ';'
FROM sys.objects AS o
INNER JOIN sys.schemas AS s
ON o.[schema_id] = s.[schema_id]
WHERE s.name = N'dbo';
PRINT @sql;
-- EXEC sp_executesql @sql;
Producirá este script (pero quizás no en este orden):
ALTER SCHEMA blat TRANSFER dbo.bar;
ALTER SCHEMA blat TRANSFER dbo.foo;
ALTER SCHEMA blat TRANSFER dbo.vFooBar;
(Es posible que desee agregar filtros adicionales para omitir objetos en el dbo
esquema que no desea mover, omitir ciertos tipos de objetos (por ejemplo, tal vez todas sus funciones son funciones de utilidad y no necesitan moverse), generar el secuencia de comandos ordenada por tipo de objeto, etc.)
Pero hay un par de problemas al mover todos sus objetos a un nuevo esquema:
Probablemente mucho su código seguirá haciendo referencia a estos objetos, ya que dbo.object
no hay una manera fácil de solucionarlo, excepto la fuerza bruta. Probablemente pueda encontrar todas las ocurrencias de manera dbo.
bastante fácil, pero también pueden devolver falsos positivos, como EXEC dbo.sp_executesql
, dbo.
en los comentarios, referencias verdaderas a objetos que permanecen en el dbo.
esquema, etc.
Sus dependencias probablemente estarán completamente fuera de control, pero no lo he probado a fondo. Sé que en este escenario:
CREATE SCHEMA blat AUTHORIZATION dbo;
GO
CREATE TABLE dbo.foo(a INT PRIMARY KEY);
CREATE TABLE dbo.bar(a INT FOREIGN KEY REFERENCES dbo.foo(a));
GO
CREATE PROCEDURE dbo.pX AS
BEGIN
SET NOCOUNT ON;
SELECT a FROM dbo.bar;
END
GO
CREATE VIEW dbo.vFooBar
AS
SELECT foo.a, bar.a AS barA
FROM dbo.foo
INNER JOIN dbo.bar
ON foo.a = bar.a;
GO
ALTER SCHEMA blat TRANSFER dbo.foo;
ALTER SCHEMA blat TRANSFER dbo.bar;
ALTER SCHEMA blat TRANSFER dbo.pX;
ALTER SCHEMA blat TRANSFER dbo.vFooBar;
Las claves externas en realidad migran más suavemente de lo que esperaba (con la advertencia que estoy probando en una versión mucho más reciente que usted). Pero debido a que el código blat.pX
todavía hace referencia dbo.bar
, obviamente ejecuta el procedimiento:
EXEC blat.pX;
Va a producir este error:
Mensaje 208, Nivel 16, Estado 1, Procedimiento pX
Nombre de objeto no válido 'dbo.bar'.
Y consultas de dependencia, como:
SELECT * FROM sys.dm_sql_referenced_entities('blat.pX', N'OBJECT');
Producirá este error:
Mensaje 2020, Nivel 16, Estado 1
Las dependencias informadas para la entidad "blat.pX" podrían no incluir referencias a todas las columnas. Esto se debe a que la entidad hace referencia a un objeto que no existe o debido a un error en una o más declaraciones de la entidad. Antes de volver a ejecutar la consulta, asegúrese de que no haya errores en la entidad y que existan todos los objetos a los que hace referencia la entidad.
Y consultando la vista:
SELECT a, barA FROM blat.vFooBar;
Produce estos errores:
Mensaje 208, Nivel 16, Estado 1, Procedimiento vFooBar
Nombre de objeto no válido 'dbo.foo'.
Msg 4413, Nivel 16, Estado 1
No se pudo usar la vista o función 'blat.vFoobar' debido a errores de enlace.
Entonces, esto podría implicar mucha limpieza. Y después de haber arreglado todas las referencias de objetos, probablemente querrá volver a compilar todos los módulos y actualizar todas las vistas en el nuevo esquema. Puede generar un script para eso bastante similar al ejemplo anterior.