如何实现100%的动态数据管道(二)

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

主要思路解决了,下面开始写详细设计(以Sybase ASE数据库为例,其他各位扩展):

1.建立中间层表vdt_columns,这个表的属性用于构建管道中的列资料.

执行类似的代码生成:

ls_sql = "create table vdt_columns ("

ls_sql +="uid int null ,"

ls_sql +="upkey varchar(1) null ,"

ls_sql +="udmid int null,"

ls_sql +="udmname varchar(30) null,"

ls_sql +="unulls varchar(1) null ,"

ls_sql +="uwidth int null ,"

ls_sql +="uscale int null,"

ls_sql +="uname varchar(30) null,"

ls_sql +="udefault varchar(255) null,"

ls_sql +="ucheck varchar(255) null,"

ls_sql +="uidentity int null"

ls_sql +=")"

EXECUTE IMMEDIATE :ls_sql using SrcSqlca;

2.构建其他相关的可能用到中间层视图:

系统对象视图:

ls_sql = 'create view vdt_objects (uid,uuid,uname,utype) as'+&

' select id,uid,name,(case type when~'TR~' then ~'T~' else type end) from sysobjects'

EXECUTE IMMEDIATE :ls_sql using SrcSqlca;

系统表视图:

ls_sql = 'create view vdt_tables (uid,uuid,uname)as'+&

' select id,uid,name from sysobjects where type = ~'U~''

EXECUTE IMMEDIATE :ls_sql using SrcSqlca;

3.初始化vdt_columns 表.

insert vdt_columns

select sc.id,so.name,sc.colid,'N',sc.type,

(case when (select count(*) from systypes st where sc.type=st.type and sc.usertype=st.usertype)=0 then (select max(st.name) from systypes st where sc.type=st.type) else (select st.name from systypes st where sc.type=st.type and sc.usertype=st.usertype) end),

'N',(case when prec is not null then isnull(sc.prec,0) else sc.length end),

sc.scale,sc.name,substring(sy.text,9,char_length(sy.text) -8),"0",(case when sc.status=128 then 1 else 0 end)

from syscolumns sc,sysobjects so ,syscomments sy

where sc.id*=so.id and sc.cdefault*=sy.id

using SrcSqlca;

在Sybase中,确定主键列比较麻烦:

declare cur_vdtcolumns cursor for

select distinct utname from vdt_columns

using SrcSqlca;

open cur_vdtcolumns;

fetch cur_vdtcolumns into :ls_utname;

do while SrcSqlca.sqlcode=0

wait(true)

ls_nulls='';ls_pkey=''

of_getnull_ase(ls_utname,ls_nulls)

of_getpk_ase(ls_utname,ls_pkey)

if len(ls_pkey)>0 then

update vdt_columns

set upkey = 'Y',unulls='N'

where CHARINDEX(uname,:ls_pkey)>0

and utname = :ls_utname

using SrcSqlca;

end if

fetch cur_vdtcolumns into :ls_utname;

loop

end if

其中of_getpk_ase()用于确定某列是否是主键.

/*Out of date*/

Long Ll_Cnt

int Li_keycnt,Li_indexid,Li_indstat,Li_indstat2

String Ls_keys,Ls_ThisKey

int Li_i

If Not IsValid(SrcSqlca) Then return -1

Select Count(*) Into :Ll_Cnt From sysobjects Where name = :as_tablename Using SrcSqlca;

If Ll_Cnt <= 0 Then

return -2

End if

DECLARE curs_sysindexes CURSOR FOR

SELECT keycnt, indid, status, status2

FROM sysindexes

WHERE id = object_id(:as_tablename) AND indid > 0 Using SrcSqlca;

OPEN curs_sysindexes ;

FETCH curs_sysindexes INTO :Li_keycnt, :Li_indexid, :Li_indstat, :Li_indstat2;

do while (SrcSqlca.Sqlcode = 0)

If Mod(int(Li_indstat2/2),2) = 1 Then

IF Mod(int(Li_indstat/2048),2) = 1 Then //主键

Ls_Keys = ''

Li_i = 1

do while Li_i <=Li_keycnt

Select distinct index_col(:as_tablename, :Li_indexid, :Li_i) into :Ls_ThisKey

From vdt_columns Using SrcSqlca;

If Isnull(Ls_ThisKey) Then

Exit

Else

If Li_i > 1 Then Ls_keys += ','

Ls_Keys += Ls_ThisKey

End if

Li_i ++

loop

End if

End if

FETCH curs_sysindexes INTO :Li_keycnt, :Li_indexid, :Li_indstat, :Li_indstat2;

loop

CLOSE curs_sysindexes;

as_keys=Ls_keys

return 1

经过以上的步骤,中间层的数据就基本获得了,根据这些数据,基本上能够无误差的传输绝大部分表.构建了中间层,为以后的不同数据库的扩展打下了一个良好的基础.

不同的数据库,构造中间层的语法各有不同,但是中间层的表(视图)的结构是一样的,这样程序中处理的方法也统一了.

待续...

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航