抛砖引玉--获得当前数据库中对象的依赖关系的算法

tjan 2003-09-11 02:12:21
create function udf_GenLevelPath()
returns @v_Result table (LevelPath int,OName sysname)
/****************************************************************/
/* 功能描述:按照依赖关系,列出数据库对象 */
/* 输入参数:无 */
/* 输出参数:按照依赖关系排列的数据库对象表,无依赖的在前 */
/* 编写:我 */
/* 时间:2003-9-9 */
/****************************************************************/
as
begin
declare @vt_ObjDepPath table (LevelPath int,OName sysname null)
declare @vt_Temp1 table (OName sysname null)
declare @vt_Temp2 table (OName sysname null)
declare @vi_LevelPath int

set @vi_LevelPath = 1
insert into @vt_ObjDepPath(LevelPath,OName)
select @vi_LevelPath,o.name
from sysobjects o
where xtype not in ('S','X')

insert into @vt_Temp1(OName)
select distinct object_name(sysdepends.depid)
from sysdepends,@vt_ObjDepPath p
where sysdepends.id <> sysdepends.depid
and p.OName = object_name(sysdepends.id)

while (select count(*) from @vt_Temp1) > 0
begin
set @vi_LevelPath = @vi_LevelPath + 1

update @vt_ObjDepPath
set LevelPath = @vi_LevelPath
where OName in (select OName from @vt_Temp1)
and LevelPath = @vi_LevelPath - 1

delete from @vt_Temp2

insert into @vt_Temp2
select * from @vt_Temp1

delete from @vt_Temp1

insert into @vt_Temp1(OName)
select distinct object_name(sysdepends.depid)
from sysdepends,@vt_Temp2 t2
where t2.OName = object_name(sysdepends.id)
and sysdepends.id <> sysdepends.depid

end

select @vi_LevelPath = max(LevelPath) from @vt_ObjDepPath

update @vt_ObjDepPath
set LevelPath = @vi_LevelPath + 1
where OName not in (select distinct object_name(sysdepends.id) from sysdepends)
and LevelPath = 1

insert into @v_Result
select * from @vt_ObjDepPath order by LevelPath desc
return
end
go

--调用方法
select * from dbo.udf_GenLevelPath()
go

...全文
166 46 打赏 收藏 转发到动态 举报
写回复
用AI写文章
46 条回复
切换为时间正序
请发表友善的回复…
发表回复
DreamManor 2003-12-31
  • 打赏
  • 举报
回复
做个标记
Primer2002cn 2003-11-10
  • 打赏
  • 举报
回复
mark
arich 2003-10-25
  • 打赏
  • 举报
回复
收藏了,学习!!

可惜我用的是MMSQL7,
不支持用户定义函数.
gq 2003-10-21
  • 打赏
  • 举报
回复
--->
表关系
可以在数据库关系图中的表间创建关系以显示某个表中的列如何链接到另一表中的列。

在关系数据库中,关系能防止冗余的数据。例如,如果正在设计一个数据库来跟踪有关书的信息,而每本书的信息(如书名、出版日期和出版商)都保存在一个名为 titles 的表中。同时还有一些想保存的有关出版商的信息,例如出版商的电话号码、地址和邮政编码。如果将所有这些信息都保存在 titles 表中,则对于某个出版商出版的每本书,出版商的电话号码将是重复的。
--->
以上是从数据库帮助中COPY的,我对表关系很生疏,不知道各位能不能讲述下他的作用,对于有关系的表3张表,如果我们建立关系,然后联合三张表查询,和不建立关系联合三张表查询,2者在性能上有多大的区别。(百W的数据量)
愉快的登山者 2003-10-20
  • 打赏
  • 举报
回复
多谢了。
Gide 2003-10-20
  • 打赏
  • 举报
回复
收藏,学习
lemon_wei 2003-10-17
  • 打赏
  • 举报
回复
收藏,学习
zlpanzy 2003-10-16
  • 打赏
  • 举报
回复
学习,
seawolfzxw 2003-10-12
  • 打赏
  • 举报
回复
收藏先
szocean 2003-10-10
  • 打赏
  • 举报
回复
好,帮你顶.
wgy2008 2003-10-09
  • 打赏
  • 举报
回复
收藏
DigJim 2003-09-30
  • 打赏
  • 举报
回复
好啊,我等着你哦!!

因为你说这个函数能判断依赖关系,所以我做了一个测试,发现了有点问题,有空我也会研究你这段代码,确实不错的东西!

我早就藏好了··
tjan 2003-09-29
  • 打赏
  • 举报
回复
不好意思,这几天忙着找栖身之地,没有来 CSDN

to Rivulet119(黑眼睛) :
你说的是正常的情况,比如根据设计好的 PowerDesigner 或 ERWin 文档生成数据库对象,这些工具会自动根据对象之间的依赖关系来生成的,不需要设计者干预,我的这个函数是在下面的实际情况下产生的:一期项目完成,没有详细文档,二期项目也没有详细文档或者文档和数据库对象不同步,在这种情况下,才产生的这个函数。
to DigJim(挖土):
1.关于类型的问题,只要修改 where xtype not in ('S','X') 即可,没有考虑把这个函数做成通用的,因为在一个公司或者项目中,需要使用这个函数的毕竟是极少数人,并且该函数也仅由于生产环境。
2.实际上,这个函数只是 DBA 维护工作中的一部分(我个人的看法,供参考),删除对象、建立对象、生成部分表的初始化的 Insert 语句,都会用到该函数,相关的内容我会在适当的时候贴出来和各位一起讨论的。
eddiezhuo 2003-09-29
  • 打赏
  • 举报
回复
学习+收藏
大健 2003-09-28
  • 打赏
  • 举报
回复
学习+收藏
DigJim 2003-09-28
  • 打赏
  • 举报
回复
我做了一个测试,发现排出来的顺序有点问题!
----------------------------------------------------------------------------
-- 原来的函数没有把主键、视图等分开!
-- 我把它改写了一下,这样就可以取出的用户表!
-- 接着我做了一个存储过程用来删除所有用户表的数据!
-- 发现排出来的数据库表的顺序有一些没有按照依赖关系排列!
----------------------------------------------------------------------------

create function udf_GenLevelPath_Table()
returns @v_Result table (LevelPath int,OName sysname,type varchar(8))
/****************************************************************/
/* 功能描述:按照依赖关系,列出数据库对象 */
/* 输入参数:无 */
/* 输出参数:按照依赖关系排列的数据库对象表,无依赖的在前 */
/* 编写:我 */
/* 时间:2003-9-9 */
/****************************************************************/
as
begin
declare @vt_ObjDepPath table (LevelPath int,OName sysname null, type Varchar(8))
declare @vt_Temp1 table (OName sysname null)
declare @vt_Temp2 table (OName sysname null)
declare @vi_LevelPath int

set @vi_LevelPath = 1
insert into @vt_ObjDepPath(LevelPath,OName,type)
select @vi_LevelPath,o.name,o.type
from sysobjects o
where xtype not in ('S','X')

insert into @vt_Temp1(OName)
select distinct object_name(sysdepends.depid)
from sysdepends,@vt_ObjDepPath p
where sysdepends.id <> sysdepends.depid
and p.OName = object_name(sysdepends.id)

while (select count(*) from @vt_Temp1) > 0
begin
set @vi_LevelPath = @vi_LevelPath + 1

update @vt_ObjDepPath
set LevelPath = @vi_LevelPath
where OName in (select OName from @vt_Temp1)
and LevelPath = @vi_LevelPath - 1

delete from @vt_Temp2

insert into @vt_Temp2
select * from @vt_Temp1

delete from @vt_Temp1

insert into @vt_Temp1(OName)
select distinct object_name(sysdepends.depid)
from sysdepends,@vt_Temp2 t2
where t2.OName = object_name(sysdepends.id)
and sysdepends.id <> sysdepends.depid

end

select @vi_LevelPath = max(LevelPath) from @vt_ObjDepPath

update @vt_ObjDepPath
set LevelPath = @vi_LevelPath + 1
where OName not in (select distinct object_name(sysdepends.id) from sysdepends)
and LevelPath = 1

insert into @v_Result
select * from @vt_ObjDepPath order by LevelPath desc
return
end
go
----------------------------------------------------------------------------
--调用方法
select * from dbo.udf_GenLevelPath_Table() where type='U'
go
----------------------------------------------------------------------------

CREATE PROCEDURE sp_ClearUserTable
AS
DECLARE @tablename varchar(50)

DECLARE c_tablename CURSOR FOR
select OName from udf_GenLevelPath_Table() where type='U'
OPEN c_tablename
FETCH NEXT FROM c_tablename INTO @tablename
WHILE @@FETCH_STATUS=0
BEGIN
EXEC('DELETE ' + @tablename )
FETCH NEXT FROM c_tablename INTO @tablename
END
CLOSE c_tablename
DEALLOCATE c_tablename
----------------------------------------------------------------------------

EXEC sp_ClearUserTable
GO


pbsql 2003-09-28
  • 打赏
  • 举报
回复
恩,不错,收藏了!
DigJim 2003-09-28
  • 打赏
  • 举报
回复
搂主,不好意思,我改了一下,使它能够返回用户定义的表

create function udf_GenLevelPath_Table()
returns @v_Result table (LevelPath int,OName sysname,type varchar(8))
/****************************************************************/
/* 功能描述:按照依赖关系,列出数据库对象 */
/* 输入参数:无 */
/* 输出参数:按照依赖关系排列的数据库对象表,无依赖的在前 */
/* 编写:我 */
/* 时间:2003-9-9 */
/****************************************************************/
as
begin
declare @vt_ObjDepPath table (LevelPath int,OName sysname null, type Varchar(8))
declare @vt_Temp1 table (OName sysname null)
declare @vt_Temp2 table (OName sysname null)
declare @vi_LevelPath int

set @vi_LevelPath = 1
insert into @vt_ObjDepPath(LevelPath,OName,type)
select @vi_LevelPath,o.name,o.type
from sysobjects o
where xtype not in ('S','X')

insert into @vt_Temp1(OName)
select distinct object_name(sysdepends.depid)
from sysdepends,@vt_ObjDepPath p
where sysdepends.id <> sysdepends.depid
and p.OName = object_name(sysdepends.id)

while (select count(*) from @vt_Temp1) > 0
begin
set @vi_LevelPath = @vi_LevelPath + 1

update @vt_ObjDepPath
set LevelPath = @vi_LevelPath
where OName in (select OName from @vt_Temp1)
and LevelPath = @vi_LevelPath - 1

delete from @vt_Temp2

insert into @vt_Temp2
select * from @vt_Temp1

delete from @vt_Temp1

insert into @vt_Temp1(OName)
select distinct object_name(sysdepends.depid)
from sysdepends,@vt_Temp2 t2
where t2.OName = object_name(sysdepends.id)
and sysdepends.id <> sysdepends.depid

end

select @vi_LevelPath = max(LevelPath) from @vt_ObjDepPath

update @vt_ObjDepPath
set LevelPath = @vi_LevelPath + 1
where OName not in (select distinct object_name(sysdepends.id) from sysdepends)
and LevelPath = 1

insert into @v_Result
select * from @vt_ObjDepPath order by LevelPath desc
return
end
go

--调用方法
select * from dbo.udf_GenLevelPath_Table() where type='U'
go
enhydraboy 2003-09-27
  • 打赏
  • 举报
回复
good
chpp_2000 2003-09-25
  • 打赏
  • 举报
回复
mark
加载更多回复(26)

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧