2011-07-07 25 views

回答

11
DECLARE @stmt nvarchar(max) = '' 
DECLARE @vw_schema NVARCHAR(255) 
DECLARE @vw_name varchar(255) 

IF OBJECT_ID('tempdb..#badViews') IS NOT NULL DROP TABLE #badViews 
IF OBJECT_ID('tempdb..#nulldata') IS NOT NULL DROP TABLE #nulldata 

CREATE TABLE #badViews 
( 
    [schema] NVARCHAR(255), 
    name VARCHAR(255), 
    error NVARCHAR(MAX) 
) 

CREATE TABLE #nullData 
( 
    null_data varchar(1) 
) 


DECLARE tbl_cursor CURSOR LOCAL FORWARD_ONLY READ_ONLY 
    FOR SELECT name, SCHEMA_NAME(schema_id) AS [schema] 
     FROM sys.objects 
     WHERE type='v' 

OPEN tbl_cursor 
FETCH NEXT FROM tbl_cursor 
INTO @vw_name, @vw_schema 



WHILE @@FETCH_STATUS = 0 
BEGIN 
    SET @stmt = 'SELECT TOP 1 * FROM ' + @vw_schema + N'.' + @vw_name 
    BEGIN TRY 
     INSERT INTO #nullData EXECUTE sp_executesql @stmt 
    END TRY 

    BEGIN CATCH 
     IF ERROR_NUMBER() != 213 BEGIN 
      INSERT INTO #badViews (name, [schema], error) values (@vw_name, @vw_schema, ERROR_MESSAGE())  
     END 
    END CATCH 


    FETCH NEXT FROM tbl_cursor 
    INTO @vw_name, @vw_schema 
END 

CLOSE tbl_cursor -- free the memory 
DEALLOCATE tbl_cursor 

SELECT * FROM #badViews 

DROP TABLE #badViews 
DROP TABLE #nullData 

更新2017年

分析破碎的依賴

根據@ robyaw的回答更新了答案。

我還修復了select語句中計算值的錯誤。看起來SELECT TOP 1 NULL from vwTestvwTest包含一個列,比如說1/0 as [Col1],但SELECT TOP 1 * from vwTest它不會拋出一個錯誤。

+0

這是一個很好的解決方案! – ibram

+1

我建議將sp_sqlexec更改爲sp_executesql。爲什麼?它在SQL Server 2000 SP3中已棄用。雖然它可能仍然適用於當前版本,但在升級時或甚至在應用下一個服務包時,它可能會停止工作。向下滾動到第三個最後一項:http://msdn.microsoft.com/en-us/site/aa215533 –

+0

謝謝,我根據你的觀察更新了它。 –

1

如果您使用SQL Server 2005或2008年,您可以在到Visual Studio 2008年或2010年導入項目,並從Visual Studio項目

1

我會備份數據庫,在我的開發機器上恢復它,在管理服務器的新窗口中創建一個包含所有視圖的腳本,放下所有視圖並嘗試執行腳本。每當視圖「損壞」時,執行就會失敗並顯示錯誤消息,例如,不存在表格或列。

2

嘗試this

呼叫sp_refreshsqlmodule所有非綁定到架構的存儲過程:

DECLARE @template AS varchar(max) 
SET @template = 'PRINT ''{OBJECT_NAME}'' 
EXEC sp_refreshsqlmodule ''{OBJECT_NAME}'' 

' 

DECLARE @sql AS varchar(max) 

SELECT @sql = ISNULL(@sql, '') + REPLACE(@template, '{OBJECT_NAME}', 
              QUOTENAME(ROUTINE_SCHEMA) + '.' 
              + QUOTENAME(ROUTINE_NAME)) 
FROM INFORMATION_SCHEMA.ROUTINES 
WHERE OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.' 
           + QUOTENAME(ROUTINE_NAME)), 
         N'IsSchemaBound') IS NULL 
     OR OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.' 
            + QUOTENAME(ROUTINE_NAME)), 
          N'IsSchemaBound') = 0 

     EXEC ( 
       @sql 
      ) 

這適用於所有視圖,函數和SP。架構綁定對象不會出現問題,無法在其上運行,這就是爲什麼它們被排除在外。

請注意,由於缺少表,SP仍然有可能在運行時失敗 - 這相當於嘗試更改該過程。

還要注意,就像ALTER一樣,它將失去UDF的擴展屬性 - 我將它們編寫成腳本並在之後恢復它們。

+0

凱德,只是好奇,如果你試圖在一個環境中,你有多個對象,打破了依賴?當我嘗試類似的東西時遇到了這個錯誤:http://connect.microsoft.com/SQLServer/feedback/details/678806/ –

+0

@Aaron Bertand - 不,這不是我真正嘗試自動化的操作,我只是代碼生成類似於上面的腳本並偶爾查看結果。如果你試圖非常主動地監視這個,這似乎是一個非常有問題的錯誤。 –

2

Adrian Iftode的解決方案很好,但如果存在與默認架構無關的視圖則失敗。是,需要架構考慮,同時還提供了對每一個失敗的觀點錯誤信息他解的修訂版(SQL Server 2012的上測試)以下:

DECLARE @stmt  NVARCHAR(MAX) = ''; 
DECLARE @vw_schema NVARCHAR(255); 
DECLARE @vw_name NVARCHAR(255); 

CREATE TABLE #badViews 
( 
     [schema] NVARCHAR(255) 
    , name  NVARCHAR(255) 
    , error  NVARCHAR(MAX) 
); 

CREATE TABLE #nullData 
( 
    null_data VARCHAR(1) 
); 

DECLARE tbl_cursor CURSOR FORWARD_ONLY READ_ONLY 
FOR 
    SELECT 
      SCHEMA_NAME(schema_id) AS [schema] 
     , name 
    FROM 
     sys.objects 
    WHERE 
     [type] = 'v'; 

OPEN tbl_cursor; 
FETCH NEXT FROM tbl_cursor INTO @vw_schema, @vw_name; 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    SET @stmt = CONCAT(N'SELECT TOP 1 NULL FROM ', @vw_schema, N'.', @vw_name); 

    BEGIN TRY 
     -- silently execute the "select from view" query 
     INSERT INTO #nullData EXECUTE sp_executesql @stmt; 
    END TRY 
    BEGIN CATCH 
     INSERT INTO #badViews ([schema], name, error) 
     VALUES (@vw_schema, @vw_name, ERROR_MESSAGE()); 
    END CATCH 

    FETCH NEXT FROM tbl_cursor INTO @vw_schema, @vw_name; 
END 

CLOSE tbl_cursor; 
DEALLOCATE tbl_cursor;  

-- print the views with errors when executed 
SELECT * FROM #badViews; 

DROP TABLE #badViews; 
DROP TABLE #nullData; 
+0

謝謝,非常好用 – mX64

相關問題