SQL Server - Как добиться хороших строк, когда один плохой (ошибка) - PullRequest
0 голосов
/ 02 июля 2019

Я пытаюсь найти ссылочные объекты, но из-за плохих ссылок на сервер есть некоторые ошибки с sys.dm_sql_referenced_entities (). Я использую try catch для обработки ошибок, но это приводит к тому, что, если повреждена только одна ссылка, другие не отображаются, и я получаю 0 строк

(затронуто 0 строк)!

На SQL2016 проблем нет, и я вижу другие строки. Как я могу получить другие строки?

BEGIN TRY
INSERT INTO @refTable
SELECT
    @nestLevel,
    @referencingEntityFullName AS referencing_object_name,
    OBJECT_ID(@referencingEntityFullName) AS referencing_object_id,
    r.referencing_minor_id, --if > 0 then computed column
    r.referenced_server_name,
    r.referenced_database_name,
    r.referenced_schema_name,
    r.referenced_entity_name,
    r.referenced_minor_name,
    r.is_caller_dependent, --warning on these!
    r.is_ambiguous--,
    --r.is_selected,
    --r.is_updated,
    --r.is_select_all,
    --r.is_insert_all,
    --r.is_all_columns_found
FROM
    sys.dm_sql_referenced_entities(@referencingEntityFullName, 'OBJECT') r
WHERE
    r.referenced_entity_name = @currentReferencedEntityName
    AND
    (
        @filterColumns = 0
        OR 
        r.referenced_minor_name IN (SELECT ColumnName FROM @piiTablesAndColumns ptac WHERE ptac.TableName = @currentReferencedEntityFullName)
        OR
        r.referenced_minor_name IS NULL --for SELECT *; check if it really works this way
    )

END TRY
BEGIN CATCH
    print('catched!')
END CATCH

Весь код:

DECLARE @piiTablesAndColumnsTmp TABLE(TableName NVARCHAR(517), ColumnNames NVARCHAR(MAX))
INSERT INTO @piiTablesAndColumnsTmp VALUES 
('dbo.stgCustomers', 'Email, PasswordHash, DateOfBirth, Title, Forename, MiddleInitial, Surname, AddressLine1, AddressLine2, AddressLine3, AddressLine4, AddressLine5, Postcode'),
('dbo.tblCustomersA', 'Email, PasswordHash, DateOfBirth, Title, Forename, MiddleInitial, Surname, AddressLine1, AddressLine2, AddressLine3, AddressLine4, AddressLine5, Postcode'),
('dbo.tblCustomersB', 'Email, PasswordHash, DateOfBirth, Title, Forename, MiddleInitial, Surname, AddressLine1, AddressLine2, AddressLine3, AddressLine4, AddressLine5, Postcode'),
('dbo.tblVIPSaleCustomers', 'MobileNumber, DateFirstLoggedIn'),
('dbo.tblVIPSaleCustomersArchive', 'MobileNumber, DateFirstLoggedIn'),
('dbo.tblOrders', 'AccountNo, PlacedDate, OrderDeliveryInstructionsID, OrderGiftMessage, OrderDeliveryRequestedTo')

--Filter root object columns if 1.
DECLARE @filterColumnsOption BIT = 1

/***
    DO NOT MODIFY BELOW HERE
**/

DECLARE @piiTablesAndColumns TABLE(TableName NVARCHAR(517), ColumnName NVARCHAR(128))

INSERT INTO @piiTablesAndColumns
    SELECT 
        piiTmp2.TableName,
        RTRIM(LTRIM( ss.data))
    FROM 
        @piiTablesAndColumnsTmp piiTmp2
        CROSS APPLY (
     SELECT
         Split.a.value('.', 'VARCHAR(100)') AS Data  
     FROM  
     (
         SELECT TableName,
             CAST ('<M>' + REPLACE(ColumnNames, ',', '</M><M>') + '</M>' AS XML) AS Data  
         FROM  @piiTablesAndColumnsTmp piiTmp
     ) AS A CROSS APPLY Data.nodes ('/M') AS Split(a) where a.TableName=piiTmp2.TableName) ss


--SELECT * FROM @piiTablesAndColumns order by 1,2

DECLARE @refTable TABLE
(
    nest_level INT,
    referencing_object_name NVARCHAR(1000),
    referencing_object_id INT,
    referencing_minor_id INT, 
    referenced_server_name NVARCHAR(1000),
    referenced_database_name NVARCHAR(1000),
    referenced_schema_name NVARCHAR(1000),
    referenced_entity_name NVARCHAR(1000),
    referenced_minor_name NVARCHAR(1000),
    is_caller_dependent BIT,
    is_ambiguous BIT--,
    --is_selected BIT,
    --is_updated BIT,
    --is_select_all BIT,
    --is_insert_all BIT,
    --is_all_columns_found BIT
);


DECLARE tableCur CURSOR FOR 
    SELECT DISTINCT ptac.TableName
    FROM @piiTablesAndColumns ptac

DECLARE @currentReferencedEntityFullName NVARCHAR(517)      

OPEN tableCur

FETCH NEXT FROM tableCur INTO @currentReferencedEntityFullName

/******* Repeats for every table */
WHILE @@FETCH_STATUS = 0
BEGIN
    print 'Processing TABLE: ' + @currentReferencedEntityFullName

    DECLARE @referencingEntities TABLE(SchemaName NVARCHAR(128), EntityName NVARCHAR(517))
    DECLARE @processedReferencedEntities TABLE (EntityName NVARCHAR(1000))

    DECLARE @currentReferencedEntityName NVARCHAR(517)
    DECLARE @currentReferencedEntityId INT 
    DECLARE @nestLevel INT = 0

    DECLARE @filterColumns BIT = @filterColumnsOption

    Start:

    SET @currentReferencedEntityId = OBJECT_ID(@currentReferencedEntityFullName)
    SET @currentReferencedEntityName = OBJECT_NAME(@currentReferencedEntityId)

    print 'Processing root: ' + @currentReferencedEntityName

    DELETE FROM @referencingEntities

    INSERT INTO @referencingEntities
    SELECT
        r.referencing_schema_name,
        r.referencing_entity_name
    FROM
        sys.dm_sql_referencing_entities(@currentReferencedEntityFullName, 'OBJECT') r
    --where
        --referencing_entity_name not in ('usp_ImportCustomerData','usp_UpdateCustomerBulkNearestStore','usp_ArchiveVipData'/*,'usp_UpdateCustomerVipSaleDeliveryStore'*/)

    DECLARE cRt CURSOR FOR SELECT SchemaName, EntityName FROM @referencingEntities
    OPEN cRt

    DECLARE @rtSchemaName NVARCHAR(128)
    DECLARE @rtEntityName NVARCHAR(517)


    FETCH NEXT FROM cRt INTO @rtSchemaName, @rtEntityName

    WHILE @@FETCH_STATUS = 0
    BEGIN
        DECLARE @referencingEntityFullName NVARCHAR(1000) = @rtSchemaName + '.' + @rtEntityName

        BEGIN TRY
        INSERT INTO @refTable
        SELECT
            @nestLevel,
            @referencingEntityFullName AS referencing_object_name,
            OBJECT_ID(@referencingEntityFullName) AS referencing_object_id,
            r.referencing_minor_id, --if > 0 then computed column
            r.referenced_server_name,
            r.referenced_database_name,
            r.referenced_schema_name,
            r.referenced_entity_name,
            r.referenced_minor_name,
            r.is_caller_dependent, --warning on these!
            r.is_ambiguous--,
            --r.is_selected,
            --r.is_updated,
            --r.is_select_all,
            --r.is_insert_all,
            --r.is_all_columns_found
        FROM
            sys.dm_sql_referenced_entities(@referencingEntityFullName, 'OBJECT') r
        WHERE
            r.referenced_entity_name = @currentReferencedEntityName
            AND
            (
                @filterColumns = 0
                OR 
                r.referenced_minor_name IN (SELECT ColumnName FROM @piiTablesAndColumns ptac WHERE ptac.TableName = @currentReferencedEntityFullName)
                OR
                r.referenced_minor_name IS NULL --for SELECT *; check if it really works this way
            )

        END TRY
        BEGIN CATCH
            print('catched!' + @referencingEntityFullName + CAST(OBJECT_ID(@referencingEntityFullName) AS VARCHAR(100)))
            raiseerror 
        END CATCH

        FETCH NEXT FROM cRt INTO @rtSchemaName, @rtEntityName
    END

    CLOSE cRt
    DEALLOCATE cRt

    --repeat for all the referencing objects to get all the data processing paths
    INSERT INTO @processedReferencedEntities VALUES ( @currentReferencedEntityFullName )
    SET @filterColumns = 0
    SET @currentReferencedEntityFullName = NULL


    SELECT TOP 1
        @currentReferencedEntityFullName = rt.referencing_object_name,
        @nestLevel = rt.nest_level + 1
    FROM 
        @refTable rt 
    WHERE 
        rt.referencing_object_name NOT IN (SELECT EntityName FROM @processedReferencedEntities)

    IF @currentReferencedEntityFullName IS NOT NULL
        GOTO Start


    FETCH NEXT FROM tableCur INTO @currentReferencedEntityFullName
END

CLOSE tableCur
DEALLOCATE tableCur


SELECT * FROM @refTable r1
where not exists (select 1 from @refTable r2 where r2.referenced_minor_name is not null and r2.referencing_object_id=r1.referencing_object_id)
ORDER BY referencing_object_name, referenced_entity_name
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...