2015-10-19 66 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