At present we have very little referential integrity, as well as having a number of tables that self-join (and indeed would perhaps better be represented as separate tables or views that joined).
The knowledge of how these tables relate to each other is implicit in the logic of the stored procedures rather than explicit in the schema. We are considering changing this.
The first step is to actually understand the implicit relationships and document them.
So my question is...
What is the best way to extract that implicit information, short of eyeballing every stored procedure. I will consider any tools, writing my own SQL to interrogate the system tables, or utilising the SQL-DMO model - or in fact anything under the sun that lets the computer do more work and me do less.
If the relationships are only identified by joins in the SPs, then you're not going to have a lot of luck automating it.
It might be worthwhile capturing queries using the profiler to find the most frequent joins first.
When it comes to refactoring, I am the old-school:
- Document what you have, use visual tool.
- Describe -- in writing -- the business model that this database captures.
- Pick-out entities out of the description nouns and the existing schema you have.
- Create a new ER model; consult with business while at it.
- Create a new DB based on the ER
- ETL data over to the new db and test.
You can use sys.sql_dependencies
to find out what columns and tables an SP depends on (helps if you don't do SELECT *
in your SPs). This will help you get an inventory of candidates at least:
referenced_major_id == the OBJECT_ID of the table
referenced_minor_id == the column id: COLUMNPROPERTY(referenced_major_id,
COLUMN_NAME,
'ColumnId')
You might have to use sp_refreshsqlmodule
to ensure that the dependencies are up to date for that to work. i.e. if you change a view, you need to sp_refreshsqlmodule
on each non-schema-bound module (obviously schema-bound modules don't allow any underlying changes changes in the first place - but you will get an error if you call sp_refreshsqlmodule
on a schema-bound object) which depended on that view. You can automate that by calling sp_refreshsqlmodule
on these objects:
SELECT *
FROM INFORMATION_SCHEMA.ROUTINES
WHERE OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.'
+ QUOTENAME(ROUTINE_NAME)),
N'IsSchemaBound') IS NULL
OR OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.'
+ QUOTENAME(ROUTINE_NAME)),
N'IsSchemaBound') = 0
来源:https://stackoverflow.com/questions/1839425/sql-server-relationships-buried-in-stored-procedures-rather-than-schema