下面是小编帮大家整理的如何实现100%的动态数据管道(二)数据库教程(共含5篇),希望对大家有所帮助。同时,但愿您也能像本文投稿人“佩佩呸”一样,积极向本站投稿分享好文章。
动态|数据
主要思路解决了,下面开始写详细设计(以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
经过以上的步骤,中间层的数据就基本获得了,根据这些数据,基本上能够无误差的传输绝大部分表.构建了中间层,为以后的不同数据库的扩展打下了一个良好的基础.
不同的数据库,构造中间层的语法各有不同,但是中间层的表(视图)的结构是一样的,这样程序中处理的方法也统一了.
待续...
动态|数据
下面看看,如何根据中间层的数据,构建管道语法:
1.首先建立一个数据窗口对象:d_vdtcolumns
SQL语法是:
SELECT vdt_columns.utid,
vdt_columns.uid,
vdt_columns.upkey,
vdt_columns.udmid,
vdt_columns.udmname,
vdt_columns.unulls,
vdt_columns.uwidth,
vdt_columns.uscale,
vdt_columns.uname,
vdt_columns.udefault,
vdt_columns.ucheck,
vdt_columns.utname,
vdt_columns.uidentity
FROM vdt_columns
WHERE utname = :as_tname
2.准备工作就绪,下面就是主战场了,开始构建数据管道.
考虑到一个管道对象可以传输多个任务,建立一个对象nvo_pipetransattrib保存传输需要的语法:
它包含了一下的instance变量:
string is_objectname //表名
string is_syntax //管道语法
string is_sconnect='zw',is_dconnect='daixf' //源数据库连接和目的数据库连接
string is_ptype,is_pcommit,is_errors //管道的几个属性
string is_sname,is_dname //源表名,目的表名
string is_sqlsyntax //管道的SQL语法
建立一个对象,从数据管道对象继承.
开始构造语法:写一个函数.
nvo_pipetransattrib inv_attrib[]
string ls_syntax,ls_sourcesyntax,ls_destsyntax
int li,lj,li_ind,li_find,li_rows,li_identity
string ls_tablename,ls_default,ls_defaultvalue,ls_pbdttype
boolean lb_find
dec ld_uwidth,ld_prec,ld_uscale
string ls_types,ls_dbtype,ls_prikey,ls_name,ls_nulls,ls_msg,ls_title='of_constrpipesyntax()'
nvo_string lnv_string
nvo_datastore lds_vdtcolumns
boolean lb_key
lds_vdtcolumns=create nvo_datastore
lds_vdtcolumns.dataobject='d_vdtcolumns'
lds_vdtcolumns.settransobject(SrcSqlca)
li=1
of_input(inv_attrib[li])
li_find=pos(inv_attrib[li].is_sqlsyntax,'*',1)
if li_find>0 then
lds_vdtcolumns.retrieve(as_tablename)
of_filterimg(lds_vdtcolumns)
li_rows=lds_vdtcolumns.rowcount()
for lj=1 to li_rows
ls_name=lds_vdtcolumns.getitemstring(lj,'uname')
ls_types=lds_vdtcolumns.getitemstring(lj,'udmname')
li_identity = lds_vdtcolumns.getitemnumber(lj,'uidentity')
ls_types=of_getpipedbtype(is_s_dbtype,ls_types)
ls_pbdttype=of_getpbdttype(is_s_dbtype,ls_types)
choose case ls_types
case 'char','varchar','nchar','nvarchar','long varchar'
if ls_types='long varchar' then ls_types='varchar'
ld_uwidth=lds_vdtcolumns.getitemnumber(lj,'uwidth')
ls_dbtype=ls_types+'('+string(int(ld_uwidth))+')'
case 'decimal','numeric'
ld_uwidth=lds_vdtcolumns.getitemnumber(lj,'uwidth')
ld_uscale=lds_vdtcolumns.getitemnumber(lj,'uscale')
if li_identity=1 then
ls_dbtype='identity'+'('+string(int(ld_uwidth))+','+string(int(ld_uscale))+')'
else
ls_dbtype=ls_types+'('+string(int(ld_uwidth))+','+string(int(ld_uscale))+')'
end if
case else
ls_dbtype=ls_types
end choose
ls_prikey=lds_vdtcolumns.getitemstring(lj,'upkey')
if ls_prikey='Y' then
lb_key=true
ls_prikey='key=yes,'
else
ls_prikey=''
end if
ls_nulls=lds_vdtcolumns.getitemstring(lj,'unulls')
if ls_nulls='Y' then
ls_nulls='yes'
else
ls_nulls='no'
end if
ls_default=isnull(lds_vdtcolumns.getitemstring(lj,'udefault'),'')
ls_sourcesyntax+=“COLUMN(type=”+ls_pbdttype+“,name=~”“+ls_name+”~“,dbtype=~”“+ls_dbtype+”~“,”+ls_prikey+“nulls_allowed=”+ls_nulls+“)~r~n”
if ls_default='' then
if li_identity = 1 then
ls_destsyntax+=“COLUMN(type=”+ls_pbdttype+“,name=~”“+ls_name+”~“,dbtype=~”“+ls_dbtype+”~“,”+ls_prikey+“nulls_allowed=”+ls_nulls+“,initial_value=~”exclude~“)~r~n”
else
ls_destsyntax+=“COLUMN(type=”+ls_pbdttype+“,name=~”“+ls_name+”~“,dbtype=~”“+ls_dbtype+”~“,”+ls_prikey+“nulls_allowed=”+ls_nulls+“)~r~n”
end if
else
if li_identity = 1 then
ls_destsyntax+=“COLUMN(type=”+ls_pbdttype+“,name=~”“+ls_name+”~“,dbtype=~”“+ls_dbtype+”~“,”+ls_prikey+“nulls_allowed=”+ls_nulls+“,default_value=~”“+ls_default+”~“,initial_value=~”exclude~“)~r~n”
else
ls_destsyntax+=“COLUMN(type=”+ls_pbdttype+“,name=~”“+ls_name+”~“,dbtype=~”“+ls_dbtype+”~“,”+ls_prikey+“nulls_allowed=”+ls_nulls+“,default_value=~”“+ls_default+”~“)~r~n”
end if
end if
next
else
return ''
end if
ls_sourcesyntax+=')'
ls_destsyntax+=')'
//generate PIPELINE
//example:
//PIPELINE(source_connect=csfdata,destination_connect=csfdata,type=replace,commit=100,errors=100,keyname=“Bar_x”)
if lb_key then
ls_syntax+='PIPELINE(source_connect='+inv_attrib[li].is_sconnect+',destination_connect='+inv_attrib[li].is_dconnect+',type='+inv_attrib[li].is_ptype+',commit='+inv_attrib[li].is_pcommit+',errors='+inv_attrib[li].is_errors+',keyname=“'+as_tablename+'_x”)~r~n'
else
ls_syntax+='PIPELINE(source_connect='+inv_attrib[li].is_sconnect+',destination_connect='+inv_attrib[li].is_dconnect+',type='+inv_attrib[li].is_ptype+',commit='+inv_attrib[li].is_pcommit+',errors='+inv_attrib[li].is_errors+')~r~n'
end if
//generate SOURCE
//example:
//SOURCE(name=“Bar”,COLUMN(type=char,name=“CustomCode”,dbtype=“char(8)”,key=yes,nulls_allowed=no)
ls_syntax+='SOURCE(name=“'+inv_attrib[li].is_sname+'”,'
ls_syntax+=ls_sourcesyntax
//generate RETRIEVE
//example:
//RETRIEVE(statement=“SELECT Bar.CustomCode,Bar.BarCode,Bar.ItemCode,Bar.Metering,Bar.PackSize,Bar.Length,Bar.Width,Bar.High,Bar.Vol,Bar.Weight,Bar.NewPackFlagFROM Bar”)
ls_syntax+='RETRIEVE(statement=“'+inv_attrib[li].is_sqlsyntax+'”)'
//generate DESTINATION
//example:
//DESTINATION(name=“Bar_copy”,
//COLUMN(type=char,name=“CustomCode”,dbtype=“char(8)”,key=yes,nulls_allowed=no,initial_value=“spaces”)
ls_syntax+='DESTINATION(name=“'+inv_attrib[li].is_dname+'”,'
ls_syntax+=ls_destsyntax
return ls_syntax
这个函数的返回值就是构建完成的管道语法了.
其中:初始化的函数:of_input(inv_attrib[li])
是初始化,inv_attrib的函数,初始化的数据主要是用户需要输入的条件,比如管道的type,commit,errors,select语句.
需要说明一下,其中处理了几个特殊的情况的函数.
of_filterimg(lds_vdtcolumns):
过滤掉表中的image列,因为管道不支持image数据传输.
of_getpipedbtype(is_s_dbtype,ls_types):
根据表中列的类型得到管道中数据列的类型,因为他们不是总是一一对应的.
这个可以通过一个extend datawindowobject,并包含有初始数据来实现.
of_getpbdttype(is_s_dbtype,ls_types):
根据表中列的类型得到管道中列的类型,因为他们也不是总是一一对应的.
这个可以通过一个extend datawindowobject,并包含有初始数据来实现.
管道语法构建完成了,就可以执行管道传输了:
this.syntax=得到的语法
li_RC = this.Start(SrcSqlca,DestSqlca,idw_Errors)
If li_RC 1 Then
if not ib_silence then msg(ls_title,“对象传输失败: ” + string(li_rc))
of_addtransmsg(' 对象<'+is_currentobj+'>传输失败:' + string(li_rc) )
return li_RC
rollback ;
else
Commit;
End if
数据
用户录入数据时经常会遇到大量重复数据,即录入下一条记录的某个字段时,其值与上一条记录同字段的值相同,如何实现数据的自动录入数据库教程
。如果编些程序自动录入相同值会大大提高录入速度。具体实现方法如下:一、程序中主要用到的函数1、FileOpen 功能:以指定的读写模式打开指定的文件,同时返回文件的句柄。2、FileWrite() 功能:从指定文件读取数据。3、FileClose() 功能:关闭先前用FileOpen()函数打开的文件。4、settext() 功能:得到当前行和列之上的编辑框中的值。5、gettext() 功能:替换在DataWindow控件或DataStore对象的当前行列的编辑框控件中的文本。6、send() 功能:向窗口发送指定的消息并立即执行相应的事件处理程序。7、describe() 功能:返回DataWindow对象或Datastore对象中的其它对象的属性值。以上函数在有关Pb的函数书中均可以找到,这里不再详述,但要注意后面两个函数的使用方法。二、具体实现方法1、建立window具体控件名称如图1所示。 2、定义实例变量数组 string is_value[] 和 integer if_File(存放打开文件的句柄)string is_columncount3、在window的Open事件中编写如下代码int iif_File = FileOpen(“Sys.ini”,LineMode!, Read!, LockRead!)is_columncount = dw_input.Describe(“DataWindow.Column.Count”) //取得DataWindow对象的总列数for i = 1 to integer(is_columncount)FileRead(if_File, is_value[i])nextFileClose(if_File)dw_input.Scrolltorow(dw_input.rowcount()) //将光标设置到最后行列dw_input.setcolumn(integer(is_columncount)) 在window 的Close事件中编写如下代码int iif_File = FileOpen(“Sys.ini”,LineMode!, Write!, LockWrite!, Replace!)for i = 1 to integer(is_columncount)FileWrite(if_File, is_value[i])nextFileClose(if_File)4、给Datawindow control自定义一个回车键事件:Event name: ue_keyenter Event ID: pbm_dwnprocessenter 5、在Datawindow control的ue_keyenter事件中写入以下代码is_value[this.getcolumn()] = this.gettext()Send(Handle(this),256,9,Long(0,0))this.settext(is_value[this.getcolumn()])return 1在Datawindow control的constructor事件中写入以下代码this.Settransobject(sqlca)this.retrieve()6、给cb_append自定义一个回车事件Event name: ue_keydown Event ID: pbm_keydown在cb_append的clicked事件中写入以下代码dw_input.Setfocus()dw_input.ScrollToRow(dw_input.InsertRow(0)) //追加一空记录并指向新记录dw_input.SetColumn(1) //指向公寓名列dw_input.Settext(is_value[1])在cb_append的ue_pbm_keydown事件中写入以下代码if keydown(keyenter!) thenthis.Triggerevent(clicked!)end if※ 注意各个控件的tab order的顺序,以上步骤只是简单的实现快速录入,如果遇到具体情况还应该做更详细的编码。动态|分组
原帖地址:
community.csdn.net/Expert/topic/3428/3428792.xml?temp=.6476251
--示例数据
create table 表(ID int,NUM int)
insert 表 select 1,2
union all select 2,3
union all select 3,2
union all select 4,2
union all select 5,12
union all select 6,2
union all select 7,1
union all select 8,5
union all select 9,1
go
/*--问题说明:
输入分组参数,比如输入 “3,6” ,实现按 ID<=3,3
输入分组参数,比如输入 “2,5,8” ,实现按 ID<=2,2
--*/
--查询的存储过程
create proc p_qry
@numlist varchar(1000)
as
set nocount on
declare @t table(id int identity,组 varchar(10),a int,b int)
declare @i int,@pnum varchar(10)
select @i=charindex(',',@numlist+',')
,@pnum=left(@numlist,@i-1)
,@numlist=stuff(@numlist,1,@i,'')
,@i=charindex(',',@numlist)
insert @t select 'id<='+@pnum,null,@pnum
while @i>0
begin
insert @t select @pnum+'
select @pnum=left(@numlist,@i-1)
,@numlist=stuff(@numlist,1,@i,'')
,@i=charindex(',',@numlist)
end
insert @t select 'id>'+@numlist,@numlist,null
select b.组,num=sum(a.num)
from 表 a,@t b
where case
when b.a is null then case when a.id<=b.b then 1 else 0 end
when b.b is null then case when a.id>b.a then 1 else 0 end
else case when a.id>b.a and a.id<=b.b then 1 else 0 end
end=1
group by b.组
order by min(b.id)
go
--调用存储过程进行查询
exec p_qry '2,5,8'
go
--删除测试
drop table 表
drop proc p_qry
/*--测试结果
组 num
---------- -----------
id<=2 5
2
id>8 1
--*/
动态
原帖地址:
community.csdn.net/Expert/topic/3452/3452577.xml?temp=.1377375
--示例数据
create table [table](A sysname,B varchar(10))
insert [table] select 'table_1','a'
union all select 'table_2','b'
create table table_1(A int)
insert table_1 select 1
union all select 2
create table table_2(A int)
insert table_2 select 3
union all select 4
go
/*--问题说明:
table中,A字段存储着其他表的名称
A字段中,记录和各个表的A字段的最大值
即得到如下结果:
table.B C
-------- -----------
a 1
b 2
--*/
--处理方法
declare @s varchar(8000)
set @s=''
select @s=@s+' when '''+A+''' then(select max(A) from ['+A+'])'
from [table] group by A
exec('select B,C=case A'+@s+' end from [table]')
go
--删除测试
drop table [table],table_1,table_2
/*--测试结果
B C
---------- -----------
a 2
b 4
--*/