数据库架构探索与DDL搜索全攻略
立即解锁
发布时间: 2025-08-30 01:40:30 阅读量: 13 订阅数: 12 AIGC 

### 数据库架构探索与DDL搜索全攻略
#### 1. 数据库对象依赖查询
在进行代码重构并确保系统稳定运行时,确定数据库对象的依赖链至关重要。当考虑重命名数据库中的对象、更改表中的列、移动模块或替换数据类型时,都需要了解这些依赖关系。
然而,从元数据中获取的依赖信息并不十分可靠。一方面,应用程序中使用的一些实体可能包含依赖调用者的引用或单部分名称引用(如未指定架构),这会导致引用实体的绑定依赖于调用者的架构,只有在代码运行时才能确定引用。另一方面,如果代码存储在字符串中并执行,代码引用的实体无法记录在元数据中。
若要检查例程(非架构绑定的存储过程、用户定义函数、视图、DML触发器、数据库级DDL触发器或服务器级DDL触发器)的依赖关系,可以更新其元数据。因为这些对象的元数据(如参数的数据类型)可能会因底层对象的更改而过时。可以使用`sys.sp_refreshsqlmodule`来更新元数据,示例如下:
```sql
sys.sp_refreshsqlmodule 'dbo.ufnGetContactInformation'
```
需要注意的是,从元数据查询中获取的信息要谨慎对待。若想采用更可靠的方法,可以考虑使用Red Gate的SQL Dependency Tracker工具。
#### 2. 查找最接近的关系
使用SQL Server 2005的目录视图`sys.sql_dependencies`,通过以下查询的变体可以轻松获取引用特定对象的对象列表以及被对象引用的对象列表:
```sql
--List all the dependencies in the database.
--Normally you'll have a WHERE clause to pick just the object you want.
SELECT Object_Schema_name(object_id) + '.' + COALESCE(OBJECT_NAME(object_id),
'unknown')
+ COALESCE('.' + COL_NAME(object_id, column_id), '') AS [referencer] ,
Object_Schema_name(referenced_major_id) + '.'
+ OBJECT_NAME(referenced_major_id)
+ COALESCE('.'
+ COL_NAME(referenced_major_id,
referenced_minor_id),
'') AS [Referenced]
FROM sys.sql_dependencies
WHERE class IN ( 0, 1 ) – -AND referenced_major_id = OBJECT_ID('HumanResources.Employee')
ORDER BY COALESCE(OBJECT_NAME(object_id), 'x') ,
COALESCE(COL_NAME(object_id, column_id), 'a')
```
#### 3. 查找依赖链
当更改对象的行为时,不仅需要知道要重构的对象的依赖对象,还需要了解这些依赖对象的依赖对象,以此类推,同时要注意相互依赖的情况。可以使用`DependencyChainOf`函数来获取依赖链,代码如下:
```sql
CREATE FUNCTION DependencyChainOf ( @Object_Name SYSNAME )
/**
summary: >
The DependencyChainOf function takes as a
parameter either a table, view, function or
procedure name or a column name. It works
best with the full object name of
schema.object(.column). Returns a table that
gives the dependency chain with both forward
and backward links so that you can see what
objects are likely to be affected by the
changes you make, and what objects your
object is referencing.
Revisions:
– version: 1
Modification: Created Table-valued
function
Author: Phil Factor
Date: 01/03/2010
– version: 2
Modification: added catch for mutual
dependency
Author: Phil Factor
Date: 02/03/2010
example:
– code:
Select distinct *
from DependencyChainOf('VEmployee')
order by The_level,TheName
– code:
EXEC sys.sp_refreshsqlmodule 'MyProc1'
Select distinct *
from DependencyChainOf('MyTable')
order by The_level,TheName
**/
RETURNS @Referenced TABLE
(
TheName VARCHAR(200) ,
The_Object_ID BIGINT ,
Column_ID INT ,
Class INT ,
The_Level INT
)
AS
BEGIN
--identify the object or column
--get the referencing entity
INSERT INTO @referenced
( The_Object_ID ,
Column_ID ,
Class ,
The_Level
)
SELECT TOP 1
object_ID ,
Column_ID ,
class ,
1
FROM ( SELECT Object_Schema_name(object_id) + '.'
+ COALESCE(OBJECT_NAME(object_id),
'unknown') + COALESCE('.'
+ COL_NAME(object_id,
column_id), '')
AS [name] ,
d.object_ID ,
d.column_ID ,
class
FROM sys.sql_dependencies d
) names
WHERE CHARINDEX(REVERSE(@Object_Name), REVERSE(names.name)) = 1
OR OBJECT_NAME([Object_ID]) = @Object_Name
IF NOT EXISTS ( SELECT 1
FROM @referenced )
INSERT INTO @referenced
( The_Object_ID ,
Column_ID ,
Class ,
The_Level
)
SELECT TOP 1
object_ID ,
Column_ID ,
class ,
1
FROM ( SELECT Object_Schema_name(referenced_major_id)
+ '.'
+ OBJECT_NAME(referenced_major_id)
+ COALESCE('.'
+ COL_NAME(referenced_major_id,
referenced_minor_id),
'') AS [name] ,
d.Referenced_Major_ID AS [object_ID] ,
d.Referenced_Minor_ID AS [column_ID] ,
class
FROM sys.sql_dependencies d
) names
WHERE CHARINDEX(REVERSE(@Object_Name),
REVERSE(names.name)) = 1
OR OBJECT_NAME([Object_ID]) = @Object_Name
DECLARE @Currentlevel INT ,
@RowCount INT
SELECT @Currentlevel = 1 ,
@Rowcount = 1
WHILE @Rowcount > 0
AND @currentLevel < 50--guard against mutual dependency
BEGIN
INSERT INTO @referenced
( The_Object_ID ,
Column_ID ,
Class ,
The_Level
)
SELECT Referenced_Major_ID ,
Referenced_Minor_ID ,
d.class ,
The_Level + 1
FROM @referenced r
INNER JOIN sys.sql_dependencies d
ON The_Object_ID = object_ID
– -AND r.column_ID=d.Column_ID
AND r.class = d.Class
AND @Currentlevel = The_Level
SELECT @rowcount = @@Rowcount ,
@CurrentLevel = @CurrentLevel + 1
END
SELECT @Currentlevel = 1 ,
@Rowcount = 1
WHILE @Rowcount > 0
AND @currentLevel > – 50--guard against mutual dependency
BEGIN
INSERT INTO @referenced
( The_Object_ID ,
Column_ID ,
Class ,
The_Level
)
SELECT Object_ID ,
d.column_ID ,
d.class ,
The_Level – 1
```
0
0
复制全文
相关推荐









