数据库

本类阅读TOP10

·SQL语句导入导出大全
·SQL Server日期计算
·SQL语句导入导出大全
·SQL to Excel 的应用
·Oracle中password file的作用及说明
·MS SQLServer OLEDB分布式事务无法启动的一般解决方案
·sqlserver2000数据库置疑的解决方法
·一个比较实用的大数据量分页存储过程
·如何在正运行 SQL Server 7.0 的服务器之间传输登录和密码
·SQL中两台服务器间使用连接服务器

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
如何实现100%的动态数据管道(二)

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

主要思路解决了,下面开始写详细设计(以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

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

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

    待续...

    

    




相关文章

相关软件