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