I have table Animal.
I want to return everything from this table + one column which denotes if record is referenced anywhere else as a foreign key.
I.E.:
Animal_Id Name
1 Cat
2 Dog
3 Parrot
I want to return this:
AnimalId Name Referenced
1 Cat true
2 Dog false
3 Parrot true
by 'referenced' I mean if a specific Animal_Id was referenced in any other table in the database as a foreign key. I think I first can query information_schema and find out what tables contain this foreign key and then use loop and dynamic sql to executeselect count(*) from eachTable where AnimalID = 1
Does anyone have a snippet on how to do that?
Using SQL Server Management Studio Open the Table Designer for the table containing the foreign key you want to view, right-click in the Table Designer, and choose Relationships from the shortcut menu. In the Foreign Key Relationships dialog box, select the relationship with properties you want to view.
The most Simplest one is by using sys. foreign_keys_columns in SQL. Here the table contains the Object ids of all the foreign keys wrt their Referenced column ID Referenced Table ID as well as the Referencing Columns and Tables.
This should do it:
SELECT OO.Animal_ID, OO.Name, CASE WHEN XX.REFERENCED IS NULL THEN 'false' ELSE 'true' END Referenced
FROM Animal OO
OUTER APPLY (SELECT SUM(1) REFERENCED
FROM (SELECT FkAnimal_ID FROM AnimalRef1 RR WHERE RR.FkAnimal_ID = OO.Animal_ID UNION ALL
SELECT FkAnimal_ID FROM AnimalRef2 RR WHERE RR.FkAnimal_ID = OO.Animal_ID UNION ALL
SELECT FkAnimal_ID FROM AnimalRef3 RR WHERE RR.FkAnimal_ID = OO.Animal_ID) II) XX
If you don't know all the FK tables, you can use system meta-data tables to generate that collection of UNION ALL queries into a table, which you could then copy & paste into your query:
WITH AKT AS ( SELECT f.name AS ForeignKey
,OBJECT_NAME(f.parent_object_id) AS TableName
,COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName
,OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName
,COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id
WHERE f.referenced_object_id = object_id('Animal'))
SELECT 'SELECT ' + ColumnName + ' FROM ' + TableName + ' WHERE RR.' + ColumnName + ' = OO.' + ReferenceColumnName + ' UNION ALL'
FROM AKT
And for the whole thing in a single query using a recursive CTE:
DECLARE @QUERY NVARCHAR(MAX)
WITH AKT AS ( SELECT ROW_NUMBER() OVER (ORDER BY f.name) RN, f.name AS ForeignKey
,OBJECT_NAME(f.parent_object_id) AS TableName
,COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName
,SCHEMA_NAME(oo.schema_id) SchemaName
,OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName
,COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id
INNER JOIN sys.objects oo ON oo.object_id = fc.referenced_object_id
WHERE f.referenced_object_id = object_id('Animal'))
,bs AS (SELECT AKT.RN
,'SELECT ' + ColumnName + ' FROM ' + SchemaName + '.' + TableName + ' WHERE ' + ColumnName + ' = OO.' + ReferenceColumnName SubQuery
FROM AKT)
,re AS (SELECT bs.RN, CAST(RTRIM(bs.SubQuery) AS VARCHAR(MAX)) Joined
FROM bs
WHERE bs.RN = 1
UNION ALL
SELECT bs2.RN, CAST(re.Joined + ' UNION ALL ' + ISNULL(RTRIM(bs2.SubQuery), '') AS VARCHAR(MAX)) Joined
FROM re, bs bs2
WHERE re.RN = bs2.RN - 1 )
,fi AS (SELECT ROW_NUMBER() OVER (ORDER BY RN DESC) RNK, Joined
FROM re)
SELECT @QUERY = 'SELECT OO.Animal_ID, OO.Name, CASE WHEN XX.REFERENCED IS NULL THEN ''No'' ELSE ''Yes'' END Referenced
FROM Animal OO
OUTER APPLY (SELECT SUM(1) REFERENCED
FROM (' + Joined + ') II) XX'
FROM fi
WHERE RNK = 1
EXEC (@QUERY)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With