烦到了极点,有兴趣的进来瞧瞧。(200分)

  • 主题发起人 babysheep
  • 开始时间
B

babysheep

Unregistered / Unconfirmed
GUEST, unregistred user!
忍受不了了,我在做一个从foxpro转数据到sqlserver的工作,当数据量超过一定量的时候,程序会出错,
我不知道是什么地方出错了,不知道是程序错误还是数据库端的错误,还是解析的错误,尝试了很多种方法,
仍未能解决,如果有哪位大侠做过这方面工作的,可以提点建议。
尝试过的测试:有个表有15000条记录,20个字段,转录了5200条
另一个表有1900条记录,115个字段,转录了400条
都是到一定的地方就会出错。实在搞不懂为什么。请各位帮忙,很急很急。

procedure TForm1.CommonTrans(Tablecode,WhereStr:string;SourceQuery,DesQuery,DesQuery2:TQuery);
var
sSql,sSqltmp,valuefield:string;
CommonVar:array[0..250,0..2] of string;//第二维数组前两位记录的是字段名和类型
KeyWordVar:array of string;
//---totalcount是被转录表的记录数,nowcount现在的记录数,nowtimes当前记录数,当达到100后重新计数
i,j,k,lenb,totalcount,nowcount,nowtimes:integer;
li1,li2:TListItem;
begin
sSql:='delete from '+Tablecode;
if not ExecuteSql(sSql,DesQuery) then exit;

sSqltmp:='';
//---从目标库字典表中查找字段名和字段类型,存放在数组中
sSql:='select FIELDCODE,FIELDTYPE from HF_FIELDDICT_MAIN '+
'where TABLECODE='''+Tablecode+'''';
if not ExecuteSql(sSql,DesQuery) then exit;
i:=0;
with DesQuery do
begin
while not eof do
begin
CommonVar[0]:=Fields[0].asstring;
CommonVar[1]:=Fields[1].asstring;
i:=i+1;
next;
end;//end while
end;//end with

//---从源库中查找表记录,然后把结果存入上述数组中
sSql:='select count(*) from '+Tablecode+' '+WhereStr;
if not ExecuteSql(sSql,SourceQuery) then exit;
totalcount:=SourceQuery.fields[0].asinteger;
nowcount:=1;
nowtimes:=1;

sSql:='select * from '+Tablecode+' '+WhereStr;
if not ExecuteSql(sSql,SourceQuery) then exit;
with SourceQuery do
begin
k:=0;
while not eof do
begin
valuefield:='';
for j:=0 to i-1 do
begin
CommonVar[j][2]:=TransChar(Fields[j].asstring,'''','"');//替换单引号
if CommonVar[j][2]='True' then
CommonVar[j][2]:='1'
else if CommonVar[j][2]='False' then
CommonVar[j][2]:='0';
//---组织插入sql语句
if (CommonVar[j][1]='N') or (CommonVar[j][1]='F') then
valuefield:=valuefield+CommonVar[j][2]
else
valuefield:=valuefield+''''+CommonVar[j][2]+'''';
valuefield:=valuefield+',';
application.ProcessMessages;
end;//end for


//---除去最后的逗号
lenb:=length(valuefield);
valuefield:=copy(valuefield,1,lenb-1);

sSqltmp:=sSqltmp+'insert into '+Tablecode+
' values('+valuefield+') ';


//---如果记录数达到100条或者到达最后一条后,则执行一次
if (nowtimes=100) or (nowcount=totalcount) then
begin
if not ExecuteSql(sSqltmp,DesQuery2) then exit;
sSqltmp:='';
nowtimes:=0;
end;//end if


next;
nowtimes:=nowtimes+1;
nowcount:=nowcount+1;
end;//end while
end;//end with


end;
 
你这样用数组中转数据内存消耗太大了,你直接转换,不要用数组.
 
是这个原因吗?我去试试
 
去掉了数组,把数据存入stringgrid中,仍未能转录成功。查到的原因好像是这样的,
我先把编号列出来(相当于关键字),然后再把其他字段放到stringgrid中,突然发现,当
到达那个错误点的时候,系统把那个编号改成了乱码,导致出错。
 
检查你的数据。
 
如此大量的数据不需要经常传输吧,如果不需要,
只是一次传输的话可以使用SQL SERVER 自带的数据导入导出工具。
另外,你写的也太复杂了。
 
1.数据是没有问题的。
2.就是因为转录工具用不了才会迫不得已自己写程序。
3.写得的确很差,请高手指点指点
 
1. 如果不考虑效率, 且数据记录是上下文无关的, 可以做一个循环一条一条转.
2. 如果考虑效率, 可以用本地文件做转存.
 
用query一次性取出大量数据,然后用next,会不会指针出错?
 
你可以用BATCHMOVE转嘛!
 
請把錯誤貼上來!
 
你这么做也太麻烦了。
两个数据库结构一样吗?
 
如果只是要做数据库的转换的话,没有必要用代码实现呀,使用datepump就可以了
 
学习学习,我也正要做这样的程序!
 
datapump和batchmove都不行,因为如果数据中有单引号的话是无法转录的。所以要自己写程序
替换掉单引号,我程序中的TransChar函数就是为了替换单引号的,如果现成工具可用的话,
我就没必要自己写程序了,可能也有我尚未接触的工具可以转录。
datapump,batchmove和sql server的导入导出都用过了,不行。

错误提示主要是关键字重复,原来的foxpro表中是没有重复的东西的,但是转录过程中
出现了,经过多方面的测试,证实不是程序问题,是数据库提取出来的时候就已经有重复,
也就是用select * from xxx写入stringgrid或者数组的时候(在sql explore中用sql语句
查看是没有重复的),不知道原因是什么,源表是没有重复数据的。
 
to mlzou
我也觉得麻烦,你有什么更好的办法吗?
数据库结构是一摸一样的,只是sqlserver这边有关键字,因为foxpro那边是没有关键字的。
也就是说,同样的一个字段在sqlserver中是关键字。但是我敢保证源表绝对没有重复数据。
 
其實導數據這樣的程序應該是很簡單
可以在Sql Server中建立相同字段名表(當然不同也可,只不過要一個個對應字段名賦值)
用Query1連FoxPro,query2連Sql Server,一條記錄一條記錄賦值
While not Query1.eof Do
begin
Query2.Append;
For i:=0 to Query1.FieldCount-1 Do
If Query2.findField(Query1.Fields[0].Fieldname)<>nil then
if Query1.Fields[0].datatype=ftstring then
Query2.findField(Query1.Fields[0].Fieldname).value:=QuotedStr(Query1.Fields[0].AsString)
else
Query2.findField(Query1.Fields[0].Fieldname).value:=Query1.Fields[0].value;
Query2.Post;
Query1.next;
end;

 
我感觉是资源占用方面的问题,应及时释放所占用的资源。
 
我的做法跟楼上的差不多,但要注意一点,当有自增字段的时候,是不允许的。
必须把自增字段刨出去。
 
顶部