Search
Home
Articles
Backup
Books
Certification
FAQ
Products
Replication
Scripts
Seminars
Training
TSQL

MSDN Fourms
Philippine SSUG
Fort Worth SSUG
Oklahoma City SSDG

Resume

MHS Enterprises
BlowFrog Software
FilAm Software
AcrylicAcetate.com
Bargain Humidors
Western Humidor

Find Foreign Keys 1 2 3 4 5

Now how does this work.  We can readily understand the following:
insert into #fkeys
        select r.rkeydbid as pkdb_id, r.rkeyid as pktable_id,...
        r.fkeydbid as fkdb_id, r.fkeyid as fktable_id,...
        r.constid as fk_id, s.constid as pk_id
        from sysreferences r, sysconstraints s, #pivot p
        where    r.rkeyid = s.id and
        (s.status & 0xf) = 1 and
        r.rkeyid between isnull(@pktable_id, 0) and isnull(@pktable_id, 0x7fffffff)
since all this does is just grab values from sysreferences and put them into the temp table.

Now for the stuff that looks really bad.  What we are taking advantage of here is a thing called characteristic functions.  These are functions that will reduce to either 0 or 1.  This is where the table called #pivot comes in.  (Don't get the name of the table confused with the operation we are perfomring.   This is a table fold and not a pivot.  But I have called this a pivot table, because it helps me conceptualize what is going on and keep things straight.  You can think of the sysreferences table like a sheet of paper.  Take a thumb tack and place it in the top left corner.  Now rotate the paper so that the long side of perpendicular to the floor.  This is what sysreferences looks like.  Now pivot the paper 90 degrees so that the short side is now perpendicular to the floor.  This is what sysreferences is going to look like.)

Keep in mind we are joining this to the #pivot table we created that has 16 rows in it numbered 1 to 16.  Now to understand this, we will walk through and evaluate each one to determine the final outcome.  (Yes, the join we have specified will produce a cross product between sysreferences and #pivot, but this is exactly what we want.) 

The first row in #pivot is 1.  We feed this into the first of the three calculations: r.rkey1 * (1 - abs(sign(p.Value - 1))).  p.Value - 1 = 0 because 1-1=0.  sign(0) = 0.  abs(0) = 0.  And 1-0 = 1.  We are then left with r.key1*1. 
Now the next one: r.rkey2 * (1 - abs(sign(p.Value - 2))).  p.Value - 2 = -1 because 1-2 = -1.  sign(-1) = -1.  abs(-1) = 1. 1-1=0.  We are then left with r.rkey2 * 0.  The same holds true for the next  14 calculations.   The result of this first one being r.rkey1 * 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 = r.rkey1. 

Now we feed in 2 which is the next value in #pivot.  r.rkey1 * (1 - abs(sign(p.Value - 1)))  p.Value - 1 = 1 because 2 -1 = 1.  sign(1) = 1.   abs(1) = 1.  1 - 1 = 0 so we are left with r.rkey1 * 0
Now the next one: r.rkey2 * (1 - abs(sign(p.Value - 2)))  p.Value - 2 = 0 because 2 - 2 = 0.  sign(0) = 0  abs(0) = 0  1 - 0 = 1 so we areleft with r.rkey2 * 1.   From this we can see that rkey3 through rkey16 will reduce to zero.

So as you can see, the table #pivot acts as a selector to zero out all but one of the columns.  This will produce and end result of 16 rows for this table that look like the following from this section:        pkcolid = r.rkey1 * (1 - abs(sign(p.Value - 1))) + r.rkey2 * (1 - abs(sign(p.Value - 2))) + r.rkey3 * (1 - abs(sign(p.Value - 3))) +
    r.rkey4 * (1 - abs(sign(p.Value - 4))) + r.rkey5 * (1 - abs(sign(p.Value - 5))) + r.rkey6 * (1 - abs(sign(p.Value - 6))) + r.rkey7 * (1 - abs(sign(p.Value - 7))) +
    r.rkey8 * (1 - abs(sign(p.Value - 8))) + r.rkey9 * (1 - abs(sign(p.Value - 9))) + r.rkey10 * (1 - abs(sign(p.Value - 10))) + r.rkey11 * (1 - abs(sign(p.Value - 11))) +
    r.rkey12 * (1 - abs(sign(p.Value - 12))) + r.rkey13 * (1 - abs(sign(p.Value - 13))) + r.rkey14 * (1 - abs(sign(p.Value - 14))) + r.rkey15 * (1 - abs(sign(p.Value - 15))) +
    r.rkey16 * (1 - abs(sign(p.Value - 16)))

rkey1

rkey2

rkey3

rkey4

rkey5

rkey6

rkey7

rkey8

rkey9

rkey10

rkey11

rkey12

rkey13

rkey14

rkey15

rkey16

Find Foreign Keys 1 2 3 4 5

Michael R. Hotek

All content on this site, except where noted, represents an original work of Michael R. Hotek and is protected by applicable copyright laws. The SQL Server FAQ is the sole work of Neil Pike. No page, portion of a page, or download may be used for commercial purposes in whole or in part without the express, written permission of the applicable author.