DbSchemaCompare is a Windows desktop tool that compares two live SQL Server databases end to end — tables, columns, indexes, constraints, views, procedures, functions, triggers, and security — and hands you a single HTML report of what's only on one side and what changed. It is strictly read-only: it only ever runs SELECT against system catalog views, never ALTER/CREATE/DROP, against either database.
A hand-written comparison built on CHECKSUM_AGG(BINARY_CHECKSUM(column_id, ...)) once flagged 12 out of 200 tables as "definition changed" — including the central 198-column table — because sys.columns.column_id keeps a gap after a column is dropped and re-added, even though the actual structure was identical. That false alarm led to two detailed wrong theories and a recommendation to rebuild a working database from scratch, before the customer's own DBA caught it. DbSchemaCompare exists so that comparison never has to be hand-rolled under time pressure again.
| Without it | With DbSchemaCompare |
|---|---|
| Ad-hoc T-SQL comparison scripts, rebuilt under time pressure each time | One tested tool, run in minutes against any two databases |
| Checksums over internal IDs report a dropped-and-readded column as "changed" | Every object matched by name and ordinal position — never column_id/object_id/index_id |
Auto-named PK/UNIQUE constraints (PK__T1__3214EC07...) look "renamed" on every server | Auto-generated constraint names detected and matched by kind + columns instead |
| Security drift (an extra DB role, a stray GRANT) goes unnoticed until an audit | DB users, roles, memberships, and permissions compared alongside the schema |
| A vague "I think X changed" claim to a customer's DBA | A precise property-level diff: exact field, old value, new value |
| Operating system | Windows 10, Windows 11, or Windows Server 2019 or later |
| Runtime | .NET Framework 4.8 — ships with Windows, nothing to install on a target DBA workstation or jump host |
| SQL Server | 2016 or later on both sides |
| Access | A login that can read the catalog views on both databases — no elevated rights, no writes |
| Dependency | Microsoft.Data.SqlClient — the only external dependency; no SMO, no ORM |
Detection and reporting only — DbSchemaCompare does not generate sync/migration scripts, and it never saves a baseline. Point it at a Source and a Target, get a report. That's the whole tool, deliberately.
Every table, index, constraint, routine, and principal is matched between Source and Target by its actual name — schema-qualified, case-insensitive — never by an instance-local identifier. Nothing in this list is a checksum or aggregate signature; every property is compared individually so a finding says exactly what changed, not just that "something" did.
| Category | What's compared |
|---|---|
| Tables & Columns | Column data type, length/precision/scale, nullability, identity, default, computed definition, ordinal position, extended properties, partitioning |
| Indexes & Constraints | Unique/clustered/primary-key flags, key and included columns, filter predicate; PK/Unique/Foreign Key/Check constraints incl. referenced table/columns and delete/update actions |
| Programmable Objects | Views, stored procedures, scalar & table-valued functions, triggers — definition text compared verbatim (whitespace-normalized) |
| Security & Other | Database users and roles, login mapping, role memberships, and permission grants — matched by principal name, not principal_id |
Every finding is one of three kinds: only in Source, only in Target, or Modified with the exact list of properties that differ — old value on the left, new value on the right.
SQL Server exposes several identifiers that look like they identify an object stably, but are actually instance-local — they mean nothing when comparing two different databases, even two copies of the exact same schema.
column_id sequence. DbSchemaCompare uses ROW_NUMBER() OVER (PARTITION BY object_id ORDER BY column_id) as the ordinal position instead — reconstructed at read time, never leaked into a comparison key.PK__T1__3214EC078C8AE89F — the hex suffix is an internal hash that differs between two servers even for a byte-for-byte identical constraint. Detected via pattern match and matched by kind + columns instead of the literal name.Both cases are regression-tested against a live SQL Server: two structurally identical tables built with these exact traps report zero differences.
Export writes a dark-theme HTML file with a summary table (counts per category and change type) followed by a detail table per category — object type, change, and every differing property with its old and new value. No server round-trip, no external assets; open it anywhere and send it as-is.
The same engine that drives the GUI runs from the command line — for a build pipeline gate, a scheduled drift check, or generating a report as a pipeline artifact.
DbSchemaCompare.exe --compare <srcServer> <srcDb> <tgtServer> <tgtDb> [--srcsqlauth <user> <pass>] [--tgtsqlauth <user> <pass>] [--report <file.html>] # headless compare, optional report
Every database interaction is a SELECT against a catalog view. The tool never issues DDL or DML against either database, and never stores a password — SQL-authenticated connections re-enter the password each session.
Target machines are DBA workstations and jump hosts that don't reliably have a modern .NET desktop runtime. .NET Framework 4.8 ships with Windows, so deployment is a folder copy — no installer, no runtime prerequisite.
DbSchemaCompare only detects and reports. A DDL generator per object type, or a saved-snapshot/baseline mode, are both real features — but each is a separate, riskier scope. This first version stays small and gets the comparison itself right.
No installer, no configuration file — connect Source and Target, pick categories, compare.
A Windows executable — copy the folder, run the exe. No installer, no separate .NET runtime, read-only against your databases.
The companion desktop tool for query health: anti-pattern scanning, execution-plan analysis, and ranked refactoring suggestions.
Get in touch about the tool, a feature, or the wider powershelldba.de toolchain.