Найдите поврежденные объекты в SQL Server

Вы можете использовать головку для этого.

Используйте

$ head --lines=-N file > new_file

, где N - количество строк, которые вы хотите удалить из файла.

Содержимое исходного файла минус последние N строк теперь находится в файле new_file

23
задан marc_s 1 March 2010 в 14:25
поделиться

10 ответов

Вас могут заинтересовать следующие статьи:

Вы можете проверить решение Майкла Дж. Сварта следующим образом:

CREATE PROCEDURE proc_bad AS
    SELECT col FROM nonexisting_table
GO

SELECT
    OBJECT_NAME(referencing_id) AS [this sproc or VIEW...],
    referenced_entity_name AS [... depends ON this missing entity name]
FROM 
    sys.sql_expression_dependencies
WHERE 
    is_ambiguous = 0
    AND OBJECT_ID(referenced_entity_name) IS NULL
ORDER BY 
    OBJECT_NAME(referencing_id), referenced_entity_name;

Что возвращает:

+------------------------+------------------------------------------+
| this sproc or VIEW...  |  ... depends ON this missing entity name |
|------------------------+------------------------------------------|
| proc_bad               |  nonexisting_table                       |
+------------------------+------------------------------------------+
17
ответ дан Daniel Vassallo 29 November 2019 в 01:29
поделиться

Два предыдущих решения здесь интересны, но оба не сработали в моих тестовых базах данных.

Оригинальный сценарий Майкла Дж. Сварта произвел для меня огромное количество ложных срабатываний, слишком много, чтобы пробиться через него. Решение Рика В. здесь было лучше - единственные ложные срабатывания, которые он дал, были для ссылок между базами данных.

Есть комментарий к статье Michael J Swart от RaduSun, которая дает решение, которое я пока не могу сломать! Вот и все, слегка подправленные для удобства чтения и моих целей, но благодарность RaduSun за логику.

SELECT 
    QuoteName(OBJECT_SCHEMA_NAME(referencing_id)) + '.' 
        + QuoteName(OBJECT_NAME(referencing_id)) AS ProblemObject,
    o.type_desc,
    ISNULL(QuoteName(referenced_server_name) + '.', '')
    + ISNULL(QuoteName(referenced_database_name) + '.', '')
    + ISNULL(QuoteName(referenced_schema_name) + '.', '')
    + QuoteName(referenced_entity_name) AS MissingReferencedObject
FROM
    sys.sql_expression_dependencies sed
        LEFT JOIN sys.objects o
            ON sed.referencing_id=o.object_id
WHERE
    (is_ambiguous = 0)
    AND (OBJECT_ID(ISNULL(QuoteName(referenced_server_name) + '.', '')
    + ISNULL(QuoteName(referenced_database_name) + '.', '')
    + ISNULL(QuoteName(referenced_schema_name) + '.', '')
    + QuoteName(referenced_entity_name)) IS NULL)
ORDER BY
    ProblemObject,
    MissingReferencedObject
10
ответ дан eftpotrm 29 November 2019 в 01:29
поделиться

Подсказка 5 для Red Gate Software содержит функцию Поиск недопустимых объектов , которая может быть полезна в этой ситуации. Инструмент выполняет поиск в базе данных объектов, которые при запуске выдают ошибку, которая звучит именно так, как вы хотите.

Вы можете бесплатно скачать 14-дневную пробную версию, чтобы попробовать и посмотреть, поможет ли она.

Пол Стивенсон
Руководитель проекта SQL Prompt
Программное обеспечение Red Gate

6
ответ дан Paul Stephenson 29 November 2019 в 01:29
поделиться

First query даст вам сломанные объекты, имя которых включает в себя Stored Procedure, View, Scalar function, DML trigger, Table-valued-function тип

/*
/////////////
////ERROR////
/////////////
All error will be listed if object is broken
*/
DECLARE @AllObjectName TABLE (
    OrdinalNo INT IDENTITY
    ,ObjectName NVARCHAR(MAX)
    ,ObjectType NVARCHAR(MAX)
    ,ErrorMessage NVARCHAR(MAX)
    )

INSERT INTO @AllObjectName (
    ObjectName
    ,ObjectType
    )
SELECT '[' + SCHEMA_NAME(schema_id) + '].[' + NAME + ']' ObjectName
    ,CASE [TYPE]
        WHEN 'P'
            THEN 'Stored Procedure'
        WHEN 'V'
            THEN 'View'
        WHEN 'FN'
            THEN 'Scalar function'
        WHEN 'TR'
            THEN 'DML trigger'
        WHEN 'TF'
            THEN 'Table-valued-function'
        ELSE 'Unknown Type'
        END
FROM sys.objects
WHERE [TYPE] IN (
        'P'
        ,'V'
        ,'FN'
        ,'TR'
        ,'TF'
        )
ORDER BY NAME

DECLARE @i INT = 1
DECLARE @RowCount INT = (
        SELECT count(1)
        FROM @AllObjectName
        )
DECLARE @ObjectName VARCHAR(MAX)

WHILE @i <= @RowCount
BEGIN
    BEGIN TRY
        SET @ObjectName = (
                SELECT ObjectName
                FROM @AllObjectName
                WHERE OrdinalNo = @i
                )

        EXEC sys.sp_refreshsqlmodule @ObjectName
    END TRY

    BEGIN CATCH
        DECLARE @message VARCHAR(4000)
            ,@xstate INT;

        SELECT @message = ERROR_MESSAGE()
            ,@xstate = XACT_STATE();

        IF @xstate = - 1
            ROLLBACK;

        UPDATE @AllObjectName
        SET ErrorMessage = @message
        WHERE OrdinalNo = @i
    END CATCH

    SET @i = @i + 1
END

SELECT ObjectName
    ,ObjectType
    ,ErrorMessage
FROM @AllObjectName
WHERE ErrorMessage IS NOT NULL

И below one поиск неразрешенных ссылок. Обычно, который рассматривается как warning, все еще может вызвать error когда-нибудь

/*
/////////////
///Warning///
/////////////
Here all warning will come if object reference is not stated properly
*/
SELECT TOP (100) PERCENT QuoteName(OBJECT_SCHEMA_NAME(referencing_id)) + '.' + QuoteName(OBJECT_NAME(referencing_id)) AS [this Object...]
    ,o.type_desc
    ,ISNULL(QuoteName(referenced_server_name) + '.', '') + ISNULL(QuoteName(referenced_database_name) + '.', '') + ISNULL(QuoteName(referenced_schema_name) + '.', '') + QuoteName(referenced_entity_name) AS [... depends ON this missing entity name]
    ,sed.referenced_class_desc
FROM sys.sql_expression_dependencies AS sed
LEFT JOIN sys.objects o ON sed.referencing_id = o.object_id
WHERE (is_ambiguous = 0)
    AND (OBJECT_ID(ISNULL(QuoteName(referenced_server_name) + '.', '') + ISNULL(QuoteName(referenced_database_name) + '.', '') + ISNULL(QuoteName(referenced_schema_name) + '.', '') + QuoteName(referenced_entity_name)) IS NULL)
    AND NOT EXISTS (
        SELECT *
        FROM sys.types
        WHERE types.NAME = referenced_entity_name
            AND types.schema_id = ISNULL(SCHEMA_ID(referenced_schema_name), SCHEMA_ID('dbo'))
        )
ORDER BY [this Object...]
    ,[... depends ON this missing entity name]

Спасибо @SQLMonger .. за предоставление мне подсказка, чтобы сделать First query, который был моим фактическим требованием

6
ответ дан Moumit 29 November 2019 в 01:29
поделиться
/*
modified version of script from http://michaeljswart.com/2009/12/find-missing-sql-dependencies/
Added columns for object types & generated refresh module command...
filter out user-define types: http://stackoverflow.com/questions/2330521/find-broken-objects-in-sql-server

* /

SELECT TOP (100) PERCENT
    QuoteName(OBJECT_SCHEMA_NAME(referencing_id)) + '.' + QuoteName(OBJECT_NAME(referencing_id)) AS [this Object...],
        o.type_desc,
    ISNULL(QuoteName(referenced_server_name) + '.', '')
    + ISNULL(QuoteName(referenced_database_name) + '.', '')
    + ISNULL(QuoteName(referenced_schema_name) + '.', '')
    + QuoteName(referenced_entity_name) AS [... depends ON this missing entity name]
    ,sed.referenced_class_desc
    ,case when o.type_desc in( 'SQL_STORED_PROCEDURE' ,'SQL_SCALAR_FUNCTION' ,'SQL_TRIGGER' ,'VIEW')
          then 'EXEC sys.sp_refreshsqlmodule ''' + QuoteName(OBJECT_SCHEMA_NAME(referencing_id)) + '.' + QuoteName(OBJECT_NAME(referencing_id)) + ''';'
          else null
       end as [Refresh SQL Module command]
FROM sys.sql_expression_dependencies as sed
LEFT JOIN sys.objects o
            ON sed.referencing_id=o.object_id
WHERE (is_ambiguous = 0)
AND (OBJECT_ID(ISNULL(QuoteName(referenced_server_name) + '.', '')
    + ISNULL(QuoteName(referenced_database_name) + '.', '')
    + ISNULL(QuoteName(referenced_schema_name) + '.', '')
    + QuoteName(referenced_entity_name)) IS NULL)
AND NOT EXISTS
   (SELECT * 
    FROM sys.types 
    WHERE types.name = referenced_entity_name 
    AND types.schema_id = ISNULL(SCHEMA_ID(referenced_schema_name), SCHEMA_ID('dbo'))
   )
ORDER BY [this Object...],
[... depends ON this missing entity name]
5
ответ дан SQLMonger 29 November 2019 в 01:29
поделиться

Начиная с SQL Server 2008, здесь используется гораздо более простой метод:

 SELECT OBJECT_NAME(referencing_id) AS 'object making reference' ,
       referenced_class_desc ,
       referenced_schema_name ,
       referenced_entity_name AS 'object name referenced' ,
       (   SELECT object_id
           FROM   sys.objects
           WHERE  name = [referenced_entity_name]
       ) AS 'Object Found?'
FROM   sys.sql_expression_dependencies e
       LEFT JOIN sys.tables t ON e.referenced_entity_name = t.name;

Как упомянуто в исходной статье ( Статья Microsoft MSDN по поиску недостающих зависимостей ), «A» Значение NULL в 'объект найден?' столбец указывает, что объект не был найден в sys.objects. "

Пример вывода:

╔═══════════════════════════════════════════════╦═══════════════════════╦════════════════════════╦═══════════════════════════════════════╦═══════════════╗
║            object making reference            ║ referenced_class_desc ║ referenced_schema_name ║        object name referenced         ║ Object Found? ║
╠═══════════════════════════════════════════════╬═══════════════════════╬════════════════════════╬═══════════════════════════════════════╬═══════════════╣
║ usvConversationsWithoutServerNotices          ║ OBJECT_OR_COLUMN      ║ dbo                    ║ ConversationLinesWithID               ║ NULL          ║
║ usvFormattedConversationLines_WithSpeakerName ║ OBJECT_OR_COLUMN      ║ dbo                    ║ ConversationLinesWithID               ║ NULL          ║
║ usvFormattedConversationLines_WithSpeakerName ║ OBJECT_OR_COLUMN      ║ dbo                    ║ FormattedConversationLines_Cached     ║ NULL          ║
║ udpCheckForDuplicates                         ║ OBJECT_OR_COLUMN      ║ dbo                    ║ FormattedConversationLines_WithChatID ║ NULL          ║
║ usvFormattedConversationsCombined             ║ OBJECT_OR_COLUMN      ║ dbo                    ║ GROUP_CONCAT_D                        ║ 178099675     ║
║ usvSequenceCrossValidationSetStudents         ║ OBJECT_OR_COLUMN      ║ dbo                    ║ usvSequenceCrossValidationSet         ║ 1406628054    ║
╚═══════════════════════════════════════════════╩═══════════════════════╩════════════════════════╩═══════════════════════════════════════╩═══════════════╝
4
ответ дан devinbost 29 November 2019 в 01:29
поделиться

Несколько лет назад я написал скрипт, который найдет хранимые процедуры, которые не будут компилироваться, потянув за текст процесса и пытаясь перекомпилировать его с помощью блока try / catch. Это довольно просто и эффективно найти хотя бы процедуры, которые можно отбросить. Вы можете легко расширить его для просмотра.

Обратите внимание, что вы должны запускать это только в среде DEV или TEST, так как она на самом деле пытается перекомпилировать процедуры.

SET NOCOUNT ON

DECLARE @ProcedureName VARCHAR(2048)
DECLARE @ProcedureBody VARCHAR(MAX)

DECLARE @RoutineName varchar(500)

DECLARE procCursor CURSOR STATIC FORWARD_ONLY READ_ONLY
 FOR
 SELECT
 --TOP 1
 SCHEMA_NAME(schema_id) + '.' + NAME AS ProcedureName,
 OBJECT_DEFINITION(o.[object_id]) AS ProcedureBody
 FROM sys.objects AS o
 WHERE o.[type] = 'P'
 ORDER BY o.[name]

OPEN procCursor
FETCH NEXT FROM procCursor INTO @ProcedureName, @ProcedureBody

WHILE @@FETCH_STATUS = 0
BEGIN
 -- Might have to play with this logic if you don't have discipline in your create statements
 SET @ProcedureBody = REPLACE(@ProcedureBody, 'CREATE PROCEDURE', 'ALTER PROCEDURE')

 BEGIN TRY
   EXECUTE(@ProcedureBody)
   PRINT @ProcedureName + ' -- Succeeded'
 END TRY
 BEGIN CATCH
   PRINT @ProcedureName + ' -- Failed: ' + ERROR_MESSAGE()
 END CATCH

 FETCH NEXT FROM procCursor INTO @ProcedureName, @ProcedureBody
END

CLOSE procCursor
DEALLOCATE procCursor

https://brettwgreen.wordpress.com/2012/12/04/find-stored-procedures-that-wont-compile/

2
ответ дан Brett Green 29 November 2019 в 01:29
поделиться

Обратите внимание, что запрос в этой теме находит недостающие объекты, а не недействительные. & Nbsp;
SQL Server не находит недопустимый объект ссылки, пока вы его не выполните.

Расширение этого запроса для обработки объектов в других схемах, а также типов:

SELECT
    '[' + OBJECT_SCHEMA_NAME(referencing_id) + '].[' + OBJECT_NAME(referencing_id) + ']' 
        AS [this sproc, UDF or VIEW...],
    isnull('[' + referenced_schema_name + '].', '') + '[' + referenced_entity_name + ']' 
        AS [... depends ON this missing entity name]
FROM 
    sys.sql_expression_dependencies
WHERE 
    is_ambiguous = 0 AND 
    (
        (
            [referenced_class_desc] = 'TYPE' and 
            TYPE_ID(
                isnull('[' + referenced_schema_name + '].', '') + 
                '[' + referenced_entity_name + ']'
            ) IS NULL
        ) or
        (   
            [referenced_class_desc] <> 'TYPE' and 
            OBJECT_ID(
                isnull('[' + referenced_schema_name + '].', '') + 
                '[' + referenced_entity_name + ']'
            ) IS NULL
        )
    )
ORDER BY 
    '[' + OBJECT_SCHEMA_NAME(referencing_id) + '].[' + OBJECT_NAME(referencing_id) + ']',
    isnull('[' + referenced_schema_name + '].', '') + '[' + referenced_entity_name + ']'
0
ответ дан AbcAeffchen 29 November 2019 в 01:29
поделиться
 create table #BrokenObjects (Name nvarchar(500), Error nvarchar(max))
 select * into #objects from(
 select name from sys.views
 union select name from sys.procedures
 union select name from sys.tables
 )x
 declare @name nvarchar(500),@err nvarchar(max)
 while exists(select top 1 * from #objects)
 begin
 select top 1 @name = name from #objects
 begin try
 EXEC sys.sp_refreshsqlmodule @name
 end try
 begin catch
 select @err = ERROR_MESSAGE()
 insert into #BrokenObjects (name,error) values (@name,@err)
 end catch
 delete from #objects
 where name = @name
 end
 drop table #objects
 select * from #BrokenObjects
 where Error not like 'Could not find object % or you do not have permission.'

 drop table #BrokenObjects
0
ответ дан Dominic H 29 November 2019 в 01:29
поделиться

Лучше всего начать с использования такого инструмента, как Visual Studio Database Edition. Его роль заключается в управлении схемой базы данных. Одна из многих вещей, которые он будет делать, - выдавать ошибку при попытке построить проект базы данных, который содержит битые объекты. Это конечно сделает намного больше чем это. Этот инструмент бесплатен для любого пользователя Visual Studio Team Suite или Visual Studio Developer Edition.

0
ответ дан Randy Minder 29 November 2019 в 01:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: