Database Schema Comparison Using Simple Queries

There are plenty of tools to compare database schemas. But why using them while SQL Server provides everything for you through System Views (check my blog How to check the schema of your Database through queries)? This blog shows you how to do that.

In this blog, we will refer to the source database as "Source", and the destination database as "Destination". They are considered in the examples as on the same server.

For each comparison, we will be checking:

  1. The new objects
  2. The objects that need to be deleted (not present in the Source database but present in the Destination database)
  3. The modified objects

First of all, we will compare the objects in the databases in order to find out what are the new objects and the objects that need to be deleted. To do that, we will use the sys.objects system view. It shows all the objects in the database, along with their object_id which is used to identify the objects in other system views:

-- Objects to be created 

    SELECT name, type_desc

    FROM Source.sys.objects

    WHERE name NOT IN (SELECT name FROM Destination.sys.objects)

 -- Objects to be deleted 

    SELECT name, type_desc

    FROM Destination.sys.objects

    WHERE name NOT IN (SELECT name FROM Source.sys.objects)

Next, we will check all the columns to see the new columns to be added, the old ones to be deleted, and the modified ones. We will use the INFORMATION_SCHEMA.COLUMNS system view:

-- Columns to be created

SELECT TABLE_SCHEMA + '.' + TABLE_NAME + '.' + COLUMN_NAME,

DATA_TYPE + ISNULL('(' + (CASE WHEN CONVERT(varchar, CHARACTER_MAXIMUM_LENGTH) = '-1' THEN 'MAX' ELSE CONVERT(varchar, CHARACTER_MAXIMUM_LENGTH) END ) + ')' , ISNULL('(' + CONVERT(varchar, NUMERIC_PRECISION) + ', ' + CONVERT(varchar, NUMERIC_SCALE) + ')', '')) + (CASE WHEN IS_NULLABLE = 'YES' THEN ', null' ELSE ', not null' END)

FROM Source.INFORMATION_SCHEMA.COLUMNS source

WHERE COLUMN_NAME NOT IN (SELECT COLUMN_NAME FROM Destination.INFORMATION_SCHEMA.COLUMNS destination

WHERE source.TABLE_NAME = destination.TABLE_NAME)

AND TABLE_NAME IN (SELECT TABLE_NAME

FROM Destination.INFORMATION_SCHEMA.TABLES)

-- Columns to be removed

SELECT TABLE_SCHEMA + '.' + TABLE_NAME + '.' + COLUMN_NAME,

DATA_TYPE + ISNULL('(' + (CASE WHEN CONVERT(varchar, CHARACTER_MAXIMUM_LENGTH) = '-1' THEN 'MAX' ELSE CONVERT(varchar, CHARACTER_MAXIMUM_LENGTH) END ) + ')' , ISNULL('(' + CONVERT(varchar, NUMERIC_PRECISION) + ', ' + CONVERT(varchar, NUMERIC_SCALE) + ')', '')) + (CASE WHEN IS_NULLABLE = 'YES' THEN ', null' ELSE ', not null' END)

FROM Destination.INFORMATION_SCHEMA.COLUMNS destination

WHERE COLUMN_NAME NOT IN (SELECT COLUMN_NAME FROM Source.INFORMATION_SCHEMA.COLUMNS source

WHERE source.TABLE_NAME = destination.TABLE_NAME)

AND TABLE_NAME IN (SELECT TABLE_NAME

FROM Source.INFORMATION_SCHEMA.TABLES)

-- Columns to be modified

SELECT source.TABLE_SCHEMA + '.' + source.TABLE_NAME + '.' + source.COLUMN_NAME,

source.DATA_TYPE + ISNULL('(' + (CASE WHEN CONVERT(varchar, source.CHARACTER_MAXIMUM_LENGTH) = '-1' THEN 'MAX' ELSE CONVERT(varchar, source.CHARACTER_MAXIMUM_LENGTH) END ) + ')' , ISNULL('(' + CONVERT(varchar, source.NUMERIC_PRECISION) + ', ' + CONVERT(varchar, source.NUMERIC_SCALE) + ')', '')) + (CASE WHEN source.IS_NULLABLE = 'YES' THEN ', null' ELSE ', not null' END),

FROM Source.INFORMATION_SCHEMA.COLUMNS source

INNER JOIN Destination.INFORMATION_SCHEMA.COLUMNS destination

ON source.TABLE_NAME = destination.TABLE_NAME

AND source.COLUMN_NAME = destination.COLUMN_NAME

WHERE source.COLUMN_DEFAULT <> destination.COLUMN_DEFAULT

OR source.DATA_TYPE <> destination.DATA_TYPE

OR source.CHARACTER_MAXIMUM_LENGTH <> destination.CHARACTER_MAXIMUM_LENGTH OR source.NUMERIC_PRECISION <> destination.NUMERIC_PRECISION

OR source.NUMERIC_SCALE <> destination.NUMERIC_SCALE

The most difficult part is to find out the updated stored procedures, user defined functions, and views. We will use the sys.sql_module system view to checkout the script of these objects. But a single space character might make 2 SPs different. We will use the DIFFERENCE function to reduce such discrepencies and focus on the script itself:

-- Changes in the SPs, Views and UDFs

SELECT o.name,

            m.definition

FROM Source.sys.sql_modules m

     INNER JOIN Source.sys.objects o ON m.object_id = o.object_id

     INNER JOIN Destination.sys.sql_modules m2      INNER JOIN Destination.sys.objects o2 ON m2.object_id = o2.object_id ON o.name = o2.name

WHERE DIFFERENCE(m.definition, m2.definition) < 4

I included the different parts in one stored procedure that produces a table with all the differences between the two databases:

CREATE PROCEDURE [dbo].[CompareSchema]

AS

CREATE TABLE #Changes

(

[Name] nvarchar(256),

[Type] nvarchar(256),

[Value] nvarchar(MAX),

[Action] nvarchar(256)

)

 

-- Objects to be created

INSERT INTO #Changes([Name], [Type], [Action])

SELECT name, type_desc, 'Create'

FROM Source.sys.objects

WHERE name NOT IN (SELECT name

FROM Destination.sys.objects)

ORDER BY type_desc, name

-- Objects to be removed

INSERT INTO #Changes([Name], [Type], [Action])

SELECT name, type_desc, 'Delete'

FROM Destination.sys.objects

WHERE name NOT IN (SELECT name

FROM Source.sys.objects)

 

-- Columns to be created

INSERT INTO #Changes([Name], [Type], [Value], [Action])

SELECT TABLE_SCHEMA + '.' + TABLE_NAME + '.' + COLUMN_NAME,

'COLUMN',

DATA_TYPE + ISNULL('(' + (CASE WHEN CONVERT(varchar, CHARACTER_MAXIMUM_LENGTH) = '-1' THEN 'MAX' ELSE CONVERT(varchar, CHARACTER_MAXIMUM_LENGTH) END ) + ')' , ISNULL('(' + CONVERT(varchar, NUMERIC_PRECISION) + ', ' + CONVERT(varchar, NUMERIC_SCALE) + ')', '')) + (CASE WHEN IS_NULLABLE = 'YES' THEN ', null' ELSE ', not null' END),

'Create'

FROM Source.INFORMATION_SCHEMA.COLUMNS source

WHERE COLUMN_NAME NOT IN (SELECT COLUMN_NAME FROM Destination.INFORMATION_SCHEMA.COLUMNS destination

WHERE source.TABLE_NAME = destination.TABLE_NAME)

AND TABLE_NAME IN (SELECT TABLE_NAME

FROM Destination.INFORMATION_SCHEMA.TABLES)

-- Columns to be removed

INSERT INTO #Changes([Name], [Type], [Value], [Action])

SELECT TABLE_SCHEMA + '.' + TABLE_NAME + '.' + COLUMN_NAME,

'COLUMN',

DATA_TYPE + ISNULL('(' + (CASE WHEN CONVERT(varchar, CHARACTER_MAXIMUM_LENGTH) = '-1' THEN 'MAX' ELSE CONVERT(varchar, CHARACTER_MAXIMUM_LENGTH) END ) + ')' , ISNULL('(' + CONVERT(varchar, NUMERIC_PRECISION) + ', ' + CONVERT(varchar, NUMERIC_SCALE) + ')', '')) + (CASE WHEN IS_NULLABLE = 'YES' THEN ', null' ELSE ', not null' END),

'Delete'

FROM Destination.INFORMATION_SCHEMA.COLUMNS destination

WHERE COLUMN_NAME NOT IN (SELECT COLUMN_NAME FROM Source.INFORMATION_SCHEMA.COLUMNS source

WHERE source.TABLE_NAME = destination.TABLE_NAME)

AND TABLE_NAME IN (SELECT TABLE_NAME

FROM Source.INFORMATION_SCHEMA.TABLES)

-- Columns to be modified

INSERT INTO #Changes([Name], [Type], [Value], [Action])

SELECT source.TABLE_SCHEMA + '.' + source.TABLE_NAME + '.' + source.COLUMN_NAME,

'COLUMN',

source.DATA_TYPE + ISNULL('(' + (CASE WHEN CONVERT(varchar, source.CHARACTER_MAXIMUM_LENGTH) = '-1' THEN 'MAX' ELSE CONVERT(varchar, source.CHARACTER_MAXIMUM_LENGTH) END ) + ')' , ISNULL('(' + CONVERT(varchar, source.NUMERIC_PRECISION) + ', ' + CONVERT(varchar, source.NUMERIC_SCALE) + ')', '')) + (CASE WHEN source.IS_NULLABLE = 'YES' THEN ', null' ELSE ', not null' END),

'Update'

FROM Source.INFORMATION_SCHEMA.COLUMNS source

INNER JOIN Destination.INFORMATION_SCHEMA.COLUMNS destination

ON source.TABLE_NAME = destination.TABLE_NAME

AND source.COLUMN_NAME = destination.COLUMN_NAME

WHERE source.COLUMN_DEFAULT <> destination.COLUMN_DEFAULT

OR source.DATA_TYPE <> destination.DATA_TYPE

OR source.CHARACTER_MAXIMUM_LENGTH <> destination.CHARACTER_MAXIMUM_LENGTH OR source.NUMERIC_PRECISION <> destination.NUMERIC_PRECISION

OR source.NUMERIC_SCALE <> destination.NUMERIC_SCALE

-- Changes in the SPs, Views and UDFs

INSERT INTO #Changes([Name], [Type], [Value], [Action])

SELECT o.name,

'SQL_STORED_PROCEDURE',

m.definition,

'Update'

FROM Source.sys.sql_modules m INNER JOIN Source.sys.objects o

ON m.object_id = o.object_id

INNER JOIN Destination.sys.sql_modules m2 INNER JOIN Destination.sys.objects o2

ON m2.object_id = o2.object_id

ON o.name = o2.name

WHERE DIFFERENCE(m.definition, m2.definition) < 4

SELECT *

FROM #Changes

The output table has the following columns:

  1. Name: the name of the object
  2. Type: the type of the object
  3. Value: the value of the object. For the columns, it will include its types, while for the SPs, Views and UDFs, it will include its scripts
  4. Action: one of the 3 possible actions: Create, Delete or Update

Output

56 Comments

  • I am so thrilled for having found your site.

  • Very nice and helpful information has been given in this article. I must say that this is a very good post.

  • I read this informative article and I really enjoy reading it. I hope see more articles on this topic by you soon.

  • Yes there should realize the reader to RSS my feed to RSS commentary, quite simply

  • You're probably sick of hearing it, but you've got a really well written blog. Keep up the the great work.

  • Thanks for taking this opportunity to converse about this, I feel strongly about this and I enjoy learning about this subject.

  • I just thought there should be a comment from a non-spam actual human who actually read through your code. Nice work man.

    - cheers!

  • Same as ken...

    Really nice work and thanks for sharing!

  • kEYRBu Major thankies for the blog.Much thanks again. Cool.

  • O2a5LX Thanks so much for the article post. Keep writing.

  • Greetings author, it is apparent that you know your subject matter and you are passionate about this topic.I realy concur with your usages and will eagerly look forward to your future updates.

  • cftgn jason pierre paul jersey
    sinle mason crosby jersey
    bhnbp frank gore jersey
    vsbrg ryan grant jersey
    vxdxk michael turner jersey

  • I visited multiple websites except the audio feature for audio songs existing at this site is in fact
    fabulous.

  • I'm really impressed with your writing skills as well as with the layout on your weblog. Is this a paid theme or did you customize it yourself? Either way keep up the excellent quality writing, it is rare to see a nice blog like this one these days.

  • Its such as you read my mind! You seem to understand a lot about this, like you wrote the ebook in it or
    something. I think that you just can do with some % to drive the message house a bit, but other than that, that is great blog. A fantastic read. I will certainly be back.

  • Way cool! Some very valid points! I appreciate you penning this write-up and also the rest of the website is really good.

  • My coder is trying to convince me to move to .net from PHP.
    I have always disliked the idea because of the expenses.

    But he's tryiong none the less. I've been using WordPress on various websites
    for about a year and am anxious about switching to another platform.

    I have heard fantastic things about blogengine.net.

    Is there a way I can transfer all my wordpress content into it?
    Any kind of help would be greatly appreciated!

  • Hello, I enjoy reading all of your article. I wanted to write a little comment to support you.

  • I couldn't refrain from commenting. Well written!

  • Somebody essentially help to make critically articles I might state.
    This is the first time I frequented your web page and to this point?
    I surprised with the research you made to create this particular post incredible.
    Fantastic activity!

  • I am not sure where you're getting your info, but good topic. I needs to spend some time learning much more or understanding more. Thanks for excellent info I was looking for this info for my mission.

  • I am sure this paragraph has touched all the internet visitors,
    its really really good post on building up new website.

  • Greetings, I think your web site may be having web browser
    compatibility problems. When I look at your website in Safari, it looks fine however,
    if opening in Internet Explorer, it has some overlapping issues.
    I just wanted to provide you with a quick heads
    up! Other than that, great blog!

  • Greetings from Ohio! I'm bored at work so I decided to browse your website on my iphone during lunch break. I love the information you present here and can't wait to take a look when I get home.
    I'm amazed at how fast your blog loaded on my cell phone .. I'm
    not even using WIFI, just 3G .. Anyways, fantastic blog!

  • Hello, i read your blog occasionally and i own a similar one and i was just wondering if you get a lot of spam comments?
    If so how do you protect against it, any plugin
    or anything you can advise? I get so much lately it's driving me insane so any assistance is very much appreciated.

  • I every time emailed this webpage post page to all my friends, as if like to read it
    afterward my friends will too.

  • Your mode of telling the whole thing in this piece of writing is genuinely
    good, every one be capable of easily understand it, Thanks a lot.

  • My programmer is trying to persuade me to move to .
    net from PHP. I have always disliked the idea because of
    the costs. But he's tryiong none the less. I've been using WordPress on a number of websites for about a
    year and am concerned about switching to another platform.
    I have heard good things about blogengine.
    net. Is there a way I can import all my wordpress content into it?
    Any kind of help would be greatly appreciated!

  • Hello, Neat post. There's an issue along with your web site in web explorer, could check this? IE still is the market chief and a huge part of other people will leave out your great writing due to this problem.

  • I like what you guys are up too. This kind of clever work and coverage!
    Keep up the awesome works guys I've added you guys to blogroll.

  • I every time spent my half an hour to read this weblog's posts everyday along with a cup of coffee.

  • I visited various blogs but the audio quality for audio
    songs present at this web site is truly marvelous.

  • I drop a leave a response whenever I appreciate a article on a site or
    I have something to add to the conversation. It is triggered by
    the fire displayed in the post I looked at. And after this post Database Schema Comparison Using
    Simple Queries - Salim Fayad. I was actually excited enough to drop a thought :
    ) I actually do have a couple of questions for you if you do not mind.
    Could it be only me or do some of the remarks come across like left
    by brain dead visitors? :-P And, if you are posting
    at additional online social sites, I would like to keep
    up with anything fresh you have to post. Could you list every one of
    your public pages like your linkedin profile, Facebook
    page or twitter feed?

  • Greetings from Los angeles! I'm bored to tears at work so I decided to check out your blog on my iphone during lunch break. I enjoy the info you provide here and can't wait to take a
    look when I get home. I'm shocked at how quick your blog loaded on my mobile .. I'm not even using WIFI,
    just 3G .. Anyways, great blog!

  • Howdy, i read your blog occasionally and i own
    a similar one and i was just curious if you get a lot of spam feedback?

    If so how do you protect against it, any plugin or anything you can recommend?
    I get so much lately it's driving me mad so any support is very much appreciated.

  • Heya i am for the first time here. I found this board and I to find It really useful & it helped me out much.
    I am hoping to offer something again and help others like you aided me.

  • My programmer is trying to persuade me to move to .
    net from PHP. I have always disliked the idea because of the
    expenses. But he's tryiong none the less. I've been using Movable-type on a variety of
    websites for about a year and am worried about switching to another platform.
    I have heard very good things about blogengine.
    net. Is there a way I can transfer all my wordpress posts into it?
    Any help would be really appreciated!

  • My coder is trying to convince me to move to .net from PHP.
    I have always disliked the idea because of the expenses.
    But he's tryiong none the less. I've been using WordPress on various websites for about a year and am
    nervous about switching to another platform.
    I have heard very good things about blogengine.net. Is there a way I can
    transfer all my wordpress content into it? Any help
    would be greatly appreciated!

  • I am really inspired together with your writing abilities as neatly as with the layout for your weblog.
    Is this a paid subject or did you modify it your self?

    Either way stay up the excellent quality writing, it is uncommon to peer a nice blog like this one today.
    .

  • Greetings! Very helpful advice in this particular article!
    It is the little changes that produce the largest changes.
    Many thanks for sharing!

  • I've been surfing on-line greater than 3 hours nowadays, yet I by no means discovered any fascinating article like yours. It's pretty price enough for me.
    In my view, if all website owners and bloggers made just
    right content material as you did, the net will
    be much more useful than ever before.

  • Terrific article! That is the type of info that should be shared around the web.
    Shame on the seek engines for not positioning
    this post upper! Come on over and visit my site . Thanks =)

  • I all the time used to read paragraph in news papers but now as I am a user of net therefore from now I am using net for articles,
    thanks to web.

  • Hi there! Someone in my Facebook group shared this website
    with us so I came to check it out. I'm definitely enjoying the information. I'm book-marking and will be tweeting this to my followers!
    Exceptional blog and fantastic style and design.

  • Heya i am for the primary time here. I came across this board and I find
    It really helpful & it helped me out much. I am hoping to
    present something again and aid others such as you aided me.

  • Heya i am for the primary time here. I came across this board and I find
    It really helpful

  • Heya i am for the primary time here. I came across this board and I find
    It really helpful

  • Greetings! Very useful advice in this particular article!
    It's the little changes which will make the greatest changes. Many thanks for sharing!

  • Hello there! This article could not be written much better!
    Looking at this article reminds me of my previous roommate!
    He continually kept talking about this. I'll forward this information to him. Pretty sure he'll have a very good read.
    Thanks for sharing!

  • 3hzLLq Very informative article post.Thanks Again. Cool.

  • Very informative blog article.Much thanks again. Awesome.

  • Very informative blog post.Really looking forward to read more. Will read on...

  • wow, awesome blog.Thanks Again. Cool.


  • Superior insight!! Useful that i'm buying setup my.

  • ?br>
    Kind marriage ceremony favors into your internet search engine and you ll get pages of internet sites providing every sort of marriage ceremony favor you could at any time wantNo denying it
    锘縔ou could do it by consuming more healthy and finding thirty minutes of bodily action 5 days a weekLet us start using the form

  • 锘縏heir performance caught the nation's attention and so people started wearing their jerseyIt
    When you've gotten together having an organization opportunity affiliate program you'll be able to possess the alternative of being able to speak to the folks who are inside the affiliateIt authorizes and conducts urine testing on its skilled atheles

Comments have been disabled for this content.