質問

I am with the task of taking an old SQL Server database and identify all of it's objects and their relationships, because the one who made it did not bother to use any foreign key, he just made all relations inside the code.

So my mission is to identify usages, relationships and make a graphic model, which I think I will use ERwin7 to do it.

I stated today taking every table name and searching it in the source-code and sql metadata. I open all those files in separated instances of Notepad++ and search to see if anyone really uses that table in the source-code or in any stored procedure or function. But there are 1500+ c# files and 857 objects in the database.

  • Is there a better way to do that?
  • Is there a tool to tell me where each table is used in the code and in the database without the need of Ctrl+F for each table name or other objects I will also check?
  • Is ER-win a reasonable choice for doing the re-modeling?
役に立ちましたか?

解決

I'm afraid I can't help with the C# code or Erwin but you can use this query for the SQL Code

SELECT * FROM sys.dm_sql_referencing_entities('dbo.ABC', 'OBJECT') 

The above query will return a list of all code objects (SPs, Functions etc) in the database that reference the object named in the initial parameter. The two part name is required. It will not unfortunately list objects that are not in the current database but it should get you started.

If you need it you can also go the other direction.

SELECT * FROM sys.dm_sql_referencing_entities('dbo.ABC', 'OBJECT') 

In this case the first parameter dbo.ABC would be a piece of code (an SP for example) and the DMO will return a list of all objects used by that SP (or whatever). From what I can tell this one WILL return objects that are in different databases or servers.

I discussed these and some other (older) options here: http://sqlstudies.com/2012/10/26/how-do-i-find-all-stored-procedures-or-views-that-use-a-specific-table/

他のヒント

Hopefully, they have named the FK's the same as the PK on the table it is linked to, this could then make it a whole lot easier. Why? What you could do is first return all the table/column names in the database with something like this:

SELECT Table_Name, Column_Name, Ordinal_Position
INTO #TempColumnNames
FROM information_schema.columns
ORDER BY Table_Name, Ordinal_Position

You could then join the table to itself based on the Column_Name, something like:

SELECT t1.Table_Name, t1.Column_Name
FROM #TempColumnNames t1
INNER JOIN #TempColumnNames t2 ON t1.Column_Name = t2.Column_Name
WHERE t1.Table_Name <> t2.Table_Name
AND t1.Ordinal_Position = 1

That should give you a long list of all the tables that have another table with the same column name in it. Remember, this is all dependent on the FK column having the same name as the PK column!

EDIT: I have edited the above to add "Ordinal_Position" which indicates the order the field appears in tables. Almost always, the PK field is listed first, but not always. Check that this is consistent in your DB. This will only link the first field that has the same name as another field and it assumes the table where that field appears first is your PK table.

You can then do something like this:

SELECT t1.Table_Name, t1.Column_Name, t2.Table_Name, t1.Ordinal_Position,
    'ALTER TABLE [' + t2.Table_Name + '] ADD CONSTRAINT FK_' + t2.Table_Name
    + '_' + t1.Table_Name + ' FOREIGN KEY (' + t1.Column_Name + ')'
    + ' REFERENCES [' + t1.Table_Name + '] (' + t1.Column_Name + ')' as FK_TSQL
FROM #TempColumnNames t1
INNER JOIN #TempColumnNames t2 ON t1.Column_Name = t2.Column_Name
WHERE t1.Table_Name <> t2.Table_Name
AND t1.ORDINAL_POSITION = 1

This should give you a whole stack of statements for creating the FK on the FK table and linking it to the PK table. Be careful though, this doesn't do it perfectly. Limitations are:

  1. PK's that are more than 1 field will not work (think of many to many link tables etc).
  2. It does not include schema's though this can be added easily (you may have multiple schemas with the same table names)
  3. You will likely still need to check RBAR (Row By Agonising Row) to ensure these are valid, but essentially you have written out all the code for creating the relationships, you just need to delete those not applicable.
ライセンス: CC-BY-SA帰属
所属していません dba.stackexchange
scroll top