SQL Server-如何在出现不良(错误)时获得良好的行

时间:2019-07-02 08:22:36

标签: sql-server tsql sql-server-2008

我尝试查找引用对象,但是由于错误的ServerLinks,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

0 个答案:

没有答案