博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

公交车路线查询系统后台数据库设计

Posted on 2009-02-14 11:57  chgBlog  阅读(409)  评论(0)    收藏  举报

应用Blog地址:

http://www.cnblogs.com/lucc/archive/2009/02/14/1390384.html

 

数据库下载(该数据库已经输入了广州市350条公交车路线作为测试数据) 

 

在《公交车路线查询系统后台数据库设计——查询算法》一文中,已经实现了查询站点到站点的路线查询算法,但是,现实中用户不一定使用站点进行查询,而是使用地名。因此,公交车查询系统数据库必需记录地名与站点的对应关系,在查询时将地名映射为站点。根据实际情况,某一地点附近通常有几个站点,因此,地名与站点之间是多对多的关系。显然,只需创建一个地名站点关系表stop_spot(Stop,Spot)用于储存这个关系即可。数据库关系图如下:

注:

Route:路线表
Stop
:站点表
Spot
:地名表
stop_route
路线-站点关系表
stop_spot
:地名-站点关系表

1.路线和地名信息管理:

以下函数用于管理公交车路线和地名的相关信息

字符串分割函数(信息处理的存储过程及查询相关的存储过程均需要使用到该函数) : 

 


/*
函数功能:将@String以@SplitChar为分隔点分割为字符串数组,结果保留在表变量中
*/

CREATE   function SplitString(
    
@String varchar(2048),
    
@SplitChar char
)
returns @res table(
    Value 
varchar(128),
    vindex 
int
)
as
begin
    
declare @index int,@unit varchar(128),@inext int,@len int,@i int
    
set @index=1
    
set @i=1
    
set @len=len(@String)
    
while @index<=@len
    
begin
        
set @inext=charindex(@SplitChar,@String,@index)
        
if @inext=0 set @inext=@len+1
        
if @inext>@index
        
begin
            
set @unit=ltrim(rtrim(substring(@String,@index,@inext-@index)))
            
if @unit<>'' 
            
begin
                
insert into @res (value,vindex) values (@unit,@i)
                
set @i=@i+1
            
end
        
end
        
set @index=@inext+1
    
end
    
return
end

 

 

插入新的公车路线: 

 


/*
插入新的公交车路线
Route:路线名
Stops:公交车经过的所有站点,站点用'-'隔开
*/

CREATE  proc InsertRoute(@Route varchar(32),@Stops_Str varchar(1024))
as
begin
    
declare @stops table(name varchar(32),position int)
    
insert @stops(name,position)
    
select Value,vIndex from dbo.SplitString(@Stops_Str,'-')

    
begin tran t1
    
save tran sp1

    
--插入路线信息
    insert into Route (name) values (@Route)
    
if(@@error<>0)
    
begin
        
rollback tran sp1
        
commit tran t1
        
raiserror('插入路线时发生错误',16,1)
        
return
    
end

    
--插入不存在的站点
    insert Stop(name)
    
select distinct name from @stops ss where name not in (select name from Stop)
    
if(@@error<>0)
    
begin
        
rollback tran sp1
        
commit tran t1
        
raiserror('插入路线时发生错误',16,1)
        
return
    
end

    
insert stop_route(Stop,Route,Position)
    
select ss.name,@Route,ss.position from @stops ss
    
if(@@error<>0)
    
begin
        
rollback tran sp1
        
commit tran t1
        
raiserror('插入路线时发生错误',16,1)
        
return
    
end

    
commit tran t1
end

 

 

插入新地名函数: 

 

InsertSpot

 

 

2.路线查询

在《公交车路线查询系统后台数据库设计——查询算法》一文中,使用储存过程InquiryT0InquiryT1InquiryT2实现了站点到站点的查询,但是地名可能对应多个站点,因此,当进行地点到地点的查询相当于站点集到站点集的查询。因此,为了支持地点到地点的查询,将InquiryT0InquiryT1InquiryT2修改为站点集到站点集的查询。以下是与查询相关的函数和存储过程:

直达路线查询: 

 


/*
查询站点@StartStops到站点@EndStops之间的直达乘车路线,多个站点用'/'分开,如:
exec InquiryT0  '站点1/站点2','站点3/站点4'
*/

CREATE   proc InquiryT0(@StartStops varchar(32),@EndStops varchar(32))
as
begin
    
declare @ss_tab table(name varchar(32))
    
declare @es_tab table(name varchar(32))
    
insert @ss_tab select Value from dbo.SplitString(@StartStops,'/')
    
insert @es_tab select Value from dbo.SplitString(@EndStops,'/')
    
if(exists(select * from @ss_tab sst,@es_tab est where sst.name=est.name))
    
begin
        
raiserror ('起点集和终点集中含有相同的站点',16,1)
        
return
    
end
    
select
        sst.name 
as 启始站点,
        est.name 
as 目的站点,
        r.Route 
as 乘坐线路,
        r.StopCount 
as 经过的站点数
    
from
        
@ss_tab sst,
        
@es_tab est,
        RouteT0 r
    
where 
        sst.name
=r.StartStop 
        
and r.EndStop=est.name
end

 

 

一次换乘查询: 

 

InquiryT1

 

 

二次换乘查询:

 

InquiryT2

 

 

综合查询: 

 

Inquiry

 

 

获取地名对应的站点: 

 

GetStopsOfSpot

 

 

如要进行地名到地名的路线查询,必需先调用GetStopsOfSpot获取地名对应的所有站点,在调用Inquiry进行查询,例如: 

 

declare @sps varchar(1024),@eps varchar(1024)
set @sps=dbo.GetStopsOfSpot('起始地点名称')
set @eps=dbo.GetStopsOfSpot('目的地点名称')
exec Inquiry @sps,@eps