2015-10-19 65 views
0

对于视图,过程,触发器和函数(在磁盘上的文件中),我有sql脚本DROP ... CREATE...。我需要运行这些脚本来更新数据库结构。更新具有依赖性的MS SQL对象

但是执行脚本的顺序很重要。因为如果view1依赖于view2,并且我先为view1运行脚本,则可能会发生错误。

假设我的脚本中没有adscititious依赖关系,所以数据库知道所有的依赖关系。

有没有一种方法可以从SQL Server中以依赖顺序选择所有这些对象名?所以我可以按照这个顺序运行脚本,不用担心上述错误。

回答

0

我写这个SQL:

SET NOCOUNT ON 
declare @deps TABLE (name nvarchar(512), dep_name nvarchar(512)) 
declare @ordered TABLE (name nvarchar(512), [level] INT) 

insert @deps(name, dep_name) 
SELECT DISTINCT CAST(OBJ.name as nvarchar(512)) AS ObjectName, 
       CAST(REFOBJ.name as nvarchar(512)) AS ReferencedObjectName 
FROM sys.sql_dependencies AS DEP 
    INNER JOIN 
    sys.objects AS OBJ 
     ON DEP.object_id = OBJ.object_id 
    INNER JOIN 
    sys.schemas AS SCH 
     ON OBJ.schema_id = SCH.schema_id 
    INNER JOIN sys.objects AS REFOBJ 
     ON DEP.referenced_major_id = REFOBJ.object_id 
    INNER JOIN sys.schemas AS REFSCH 
     ON REFOBJ.schema_id = REFSCH.schema_id 
    LEFT JOIN sys.columns AS REFCOL 
     ON DEP.class IN (0, 1) 
      AND DEP.referenced_minor_id = REFCOL.column_id 
      AND DEP.referenced_major_id = REFCOL.object_id 
WHERE OBJ.type_desc IN ('VIEW','SQL_STORED_PROCEDURE','SQL_INLINE_TABLE_VALUED_FUNCTION','SQL_TRIGGER','SQL_SCALAR_FUNCTION') 
    AND REFOBJ.type_desc IN ('VIEW','SQL_STORED_PROCEDURE','SQL_INLINE_TABLE_VALUED_FUNCTION','SQL_TRIGGER','SQL_SCALAR_FUNCTION') 

insert @ordered(name, [level]) 
select distinct d1.dep_name, 1 as [level] 
from @deps d1 
    LEFT JOIN @deps d2 ON d1.dep_name = d2.name 
where d2.name IS NULL 

WHILE EXISTS(select * from @deps) 
BEGIN 
    delete d 
    FROM @deps d 
     JOIN @ordered o ON d.name = o.name 

    insert @ordered(name, [level]) 
    SELECT DISTINCT d0.name, (select MAX([level]) + 1 FROM @ordered) 
    FROM @deps d0 
     LEFT JOIN (
      SELECT d.name 
      from @deps d 
       LEFT JOIN @ordered o ON d.dep_name = o.name 
      WHERE o.name IS NULL 
     ) dfilter ON d0.name = dfilter.name 
    WHERE dfilter.name is NULL 
END 

select * from @ordered 
ORDER by level asc