SQL Question

How to compare all columns of all tables from two databases

I have two databases. One is for transaction purposes and another is for auditing purposes. The database names are

CLX_DEVELOPMENT
and
CLX_DEVELOPMENT_AUDIT
. Both the databases should have the same number of tables and columns.

My requirement is I have to check whether any column is missing in
CLX_DEVELOPMENT_AUDIT
.

Answer

This will return columns from one database that are not present in the corresponding table of the other database:

WITH DB1 AS (
    SELECT objects.name AS TBL, columns.name AS COL
    FROM       CLX_DEVELOPMENT.sys.objects 
    INNER JOIN CLX_DEVELOPMENT.sys.columns ON objects.object_id = columns.object_id
    WHERE objects.type = 'U' -- user table
), DB2 AS (
    SELECT objects.name AS TBL, columns.name AS COL
    FROM       CLX_DEVELOPMENT_AUDIT.sys.objects 
    INNER JOIN CLX_DEVELOPMENT_AUDIT.sys.columns ON objects.object_id = columns.object_id
    WHERE objects.type = 'U' -- user table
)
SELECT DB1.TBL, DB1.COL
FROM DB1
LEFT JOIN DB2 ON DB1.TBL = DB2.TBL and DB1.COL = DB2.COL
WHERE DB2.TBL IS NULL

A more generic solution that generates a column diff of two databases is as follows:

WITH CTE AS (
    SELECT TABLE_NAME, COLUMN_NAME FROM Database1.INFORMATION_SCHEMA.COLUMNS
    UNION
    SELECT TABLE_NAME, COLUMN_NAME FROM Database2.INFORMATION_SCHEMA.COLUMNS
)
SELECT CTE.TABLE_NAME, CTE.COLUMN_NAME, CASE
    WHEN DB1.COLUMN_NAME IS NULL THEN 'DB2 Only'
    WHEN DB2.COLUMN_NAME IS NULL THEN 'DB1 Only'
    ELSE 'BOTH DB'
END AS [Present In]
FROM CTE
LEFT JOIN Database1.INFORMATION_SCHEMA.COLUMNS AS DB1 ON CTE.TABLE_NAME = DB1.TABLE_NAME AND CTE.COLUMN_NAME = DB1.COLUMN_NAME
LEFT JOIN Database2.INFORMATION_SCHEMA.COLUMNS AS DB2 ON CTE.TABLE_NAME = DB2.TABLE_NAME AND CTE.COLUMN_NAME = DB2.COLUMN_NAME
WHERE DB1.COLUMN_NAME IS NULL OR DB2.COLUMN_NAME IS NULL