TXT文件导入MSSQL数据库,急呀!!(100分)

  • 主题发起人 主题发起人 LoveDelphiX
  • 开始时间 开始时间
L

LoveDelphiX

Unregistered / Unconfirmed
GUEST, unregistred user!
[8D]各位DFW,救我呀,怎么把TXT文件导入数据,通过DELPHI代码实现,不用DTS服务的
 
自己写函数来处理了。
 
简单,MSsql本身就替你想到过这一点
BCP技术,在微软的几乎所有产品之间,都可以任意导入导出数据,而且中间格式就是TXT
BCP=BULK COPY PROTECOL,你去sql里看看,n多帮助的
 
to foxphone2003
能不能具体的写点代码的呀,我急着用的,没有时间研究
 
1,把txt读入一个stringlist中,然后分析并插入.
2,轉載一下別人的代碼,你自己調試一下.

话题1714905的标题是: 如何将文本文件导入SQL (100分)
分类:数据库-文件型 krisjim (2003-03-27 14:32:00)
Afghanistan. 101. 阿富汗.
Africa. 200. 非洲.
Albania. 313. 阿尔巴尼亚.
Algeria. 201. 阿尔及利亚.
Andorra. 314. 安道尔.

以上是一个TXT文件, 如何将内容分三个字段转出到SQL.
字段1 字段2 字段3
Afghanistan. 101. 阿富汗.
Africa. 200. 非洲.
Albania. 313. 阿尔巴尼亚.
Algeria. 201. 阿尔及利亚.
Andorra. 314. 安道尔.

smokingroom (2003-03-27 14:45:00)
procedure TForm1.Button2Click(Sender: TObject);
var
F:TextFile;
Str:string;
Field1,Field2,Field3:string;
begin
AssignFile(F,'c:/aa.txt');
Reset(F);
Field1:='';
Field2:='';
Field3:='';
while not Eof(F) do
begin
Readln(F,Str);
if Pos('.',Str)>0 then
begin
Field1:=Copy(Str,1,Pos('.',Str));
Str:=Copy(Str,Pos('.',Str)+1,Length(Str));
Field2:=Copy(Str,1,Pos('.',Str));
Str:=Copy(Str,Pos('.',Str)+1,Length(Str));
Field3:=Str;
end;
AppendNewRecord(Field1,Field2,Field3);
end;
CloseFile(F);
end;

procedure TForm1.AppendNewRecord(Field1,Field2,Field3:string);
begin
with ADOQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('INSERT TableName(Filed1,Field2,Field3) VALUES(:FiledValue1,:FiledValue2,:FieldValue3)');
Parameters[0].Value:=Field1;
Parameters[1].Value:=Field2;
Parameters[2].Value:=Field3;
ExecSQL;
end;
end;

pdb (2003-03-27 14:53:00)
給分,老大:
procedure TForm1.Button1Click(Sender: TObject);
Var Str,FileName:String;index,i,j:Integer;
ListTxt:TStringList;FS: TFileStream;
begin
FileName:='c:/aa.txt'; //文件名
If Not FileExists(FileName) then
begin
Showmessage('找不到該文件:'+FileName+',請確認!');
Exit;
end;
//以下是將文件的內容裝到列表里;
FS :=TFileStream.Create(FileName,fmShareDenyNone);
ListTxt:=TStringList.Create;
LIstTxt.LoadFromStream(Fs);
//打開數據庫表
ADOQuery1.close;
ADOQuery1.sql.text:='select f1,f2,f3 from 表名';
ADOQuery1.Open;
index:=-1;
For i:=0 to ListTxt.Count-1 do
begin
ADOQuery1.Append;
Str:='';
Index:=-1;
for j:=1 to Length(ListTxt) do
If (ListTxt[j]<>'.')And(j<>Length(ListTxt))then
Str:=Str+ListTxt[j]
Else begin
Index:=index+1;
ADOQuery1.Fields[index].AsString:=Str;
Str:='';
end;
If ADOQuery1.Modified then ADOQuery1.Post
Else ADOQuery1.Cancel;
end;
end;


book523 (2003-03-27 15:52:00)
楼上的方法可行,但是速度上有点慢。
不知有没有更好的方法?
 
对的,等等最优方案,下午散分。
 
话题523759的标题是: 如何高效的将.txt文本导入/出table中? (200分)
分类:数据库-C/S型 xfwing (2001-05-07 9:59:00)
如何高效的将.txt文本导入/出table中,
类似PB中的importfile和saveas的功能.
我自己写函数效率很低,与PB相比速度上
有十倍以上的差距。
我post出我的code
******************
var
fp:Textfile;
I:integer;
strRecord:string;
buf:array[1..1024] of char;
begin
assignfile(fp,'test.txt');
System.SetTextBuf(fp, Buf);
rewrite(fp);
adoquery1.Open;
adoquery1.first;
while not(adoquery1.Eof) do
begin
strRecord:='';
for I:=0 to adoquery1.FieldCount-1 do
strRecord:=strRecord+trim(adoquery1.fields.asstring)+#9;
try
writeln(fp,strRecord);
except
closefile(fp);
end;
adoquery1.Next;
end;
closefile(fp);
adoquery1.Close;
end;
**************
我想用ADO connect数据库,不用BDE.所以不用 delphi 的 *.sch
用以上的code三万笔数据须10分钟左右.
而用pb中的saveas函数导出只须一两分钟.
我找到一个元件TPgCSV用来import/export文本数据,
但我看到source中的方法和我一样,效率很低.
不知各位有何其他方法,请指教.



zqs10597249 (2001-05-11 8:40:00)
xfwing, 我是参考别人的,如下,你看看

用Delphi实现将纯文本资料转入数据库

  在我们日常工作中,常会碰到这样一个难题:一大堆收集好的纯文本格式,比较规整的资料怎样才能将它们分离,转到自己已经建好的数据库中进行管理呢?例如,有一段人事档案资料document.txt,内容如下:

  张强,25,助理工程师,

  王宏,30,工程师,

  李远,45,高级工程师,

  要将它转入数据库中,document.db结构如下:

  姓名,年龄,职称

  怎么办呢?现在通过使用delphi编程,很好地解决了这个难题。
Delphi提供了许多功能强大,丰富的字符处理函数和过程,常用的有:

  ① function Length(S:String):Integer  //返回串的长度

  ② function Copy(S:String; Index,Count: Integer):String

  //给出一个字符串中串的拷贝

  ③ function Pos(Substr:String; S:String); Integer  

  //查找子串在字符串中的位置

  ④ Procedure Delete(Var S:String; Index,Count: Integer);

  //从一个字符串中去除子串

  利用Delphi提供的已有函数和过程基础上编制自己的三个函数,
实现了纯文本格式资料转入数据库功能。只要Delphi支持的数据库都可以支持。

  Document.txt中每行数据为一个字符串,字符串中每个被分割的数据为一个字段,
分割每个字段的字符为分割符,这里是逗号,也可以是、;#等符号。
具体思想是:先将字符串进行调整,然后把串中每个字符同分割符比较,
将不是分割符的字符追加到MyStr串中,最后得到一个字段的内容。通过一个循环,
就可以将一个字符串分成几个字段。

  Function GetSubStr(var aString:string; SepChar:String): String;

  //得到字符串中一个子串

  因要改变参数aString的值,所以将它用var定义。

  Function GetSubStrNum(aString, SepChar: String): Integer;

  //计算一个字符串要被分割成几个字段。

  参数:aString是所需分割的一个字符串,

  SepChar是分割符。
  Function GetSubStrNum(aString:String;SepChar:String):integer;
  var
  i:Integer;
  StrLen:Integer;
  Num:Integer;
  begin
  StrLen:=Length(aString);
  Num:=0;
  For i:=1 to StrLen do
  If Copy(aString,i,1) = SepChar then
  Num:=Num+1;
  result:=Num;
  end;
  Function GetSubStr(var aString:String;SepChar:String):String;
  var
  Mystr:String;
  StrLen:Integer;
  SepCharPos:Integer;
  begin
  StrLen:=Length(aString);
  SepCharPos:=Pos(SepChar,aString); //计算分割符在子串中的位置
  MyStr:=Copy(aString,1,SepCharPos-1); //将分割符前所有字符放到mystr串中
  Delete(aString,1,SepCharPos); //除去分割符和分割符前的子串
  GetSubStr:=MyStr; //返回一个字段
  end;

  有了上面三个函数,现在介绍一下具体的应用:

  ① 首先建立一个窗体Forml,加入一个RichEditl(或Menol),
一个按钮Buttonl和一个Tablel,设置Tablel的属性:

  Tablell.DataBaseName:= 'c:/test';

  Tablell.TableName:= 'document.db';

  ② 分别加入以下程序:

  const
  SepChar=',' ;
  procedure TForm1.FormCreate(Sender: TObject);
  begin
  RichEdit1.Lines.LoadFromFile('c:/test/test.txt');
  end;
  procedure TForm1.Button1Click(Sender: TObject);
  var
  i,j,num:Integer;
  MyLine:String;
  item:array[1..3] of string;
  begin
  For i:=0 to RichEdit1.Lines.Count-1 do
  begin
  MyLine:=Richedit1.Lines;
  num:=GetSubStrNum(myline,SepChar);
  for j:=1 to num do
  item[j]:=GetSubStr(myline,SepChar);
  table1.open;
  with table1 do
  begin
  table1.insert;
  table1name.Asstring:=item[1];
  table1age.Asinteger:=strtoint(item[2]);
  table1title.Asstring:=item[3];
  table1.post;
  end;
  table1.close;
  end;
  end;

wgzhang (2001-05-11 9:06:00)
procedure TForm1.Button1Click(Sender: TObject);
var TextList:Tstringlist;
LineStr:string;
LineNo:integer;
begin
Textlist:=Tstringlist.create;
if opendialog1.Execute then
begin
Textlist.LoadFromFile(opendialog1.filename);
LineNo:=0;
while LineNo<TextList.Count do
begin
LineStr:=Textlist[LineNo];
Table1.InsertRecord(Copy(LineStr,1,4),Copy(LineStr,5,10),Copy(LineStr,16,10));
Inc(LineNo);
end;
end;
TextList.Free;
end;
试试看吧,速度很快。

fontain (2001-09-10 18:16:00)
那么麻烦,
先建立一个连接,然后
adoconnection1.execute('select * into [text;database=d:/].aa from bbb');
adoconnection1.execute('select * into aa from [text;database=d:/].bbb');
ok,很快


李稻 (2001-09-11 10:20:00)
建立二个数据库别名,用batchmove控件,很快

zhangyvping (2001-09-29 10:20:00)
bcp table_name out you.dat -n -k -SSQL_SERVER服务器名 -Usa -P密码
bulk insert table_name from you.dat
WITH (
DATAFILETYPE = 'native',
FIELDTERMINATOR = ',',
KEEPNULLS,
TABLOCK,
)

wangpian (2001-09-29 13:02:00)
是导出数据慢,还是导入慢?
导出慢,可能跟你的ADO的光标类型有关。
导入慢,可以一次提交100行代码

billy_yuan (2001-09-29 13:35:00)
你的数据库如果是MSSQL和INERTBASE,可以用EXTERNAL 试试
insert into table select * from external 'tablename.dbf'

stjsq (2001-09-29 22:49:00)
to fontain:我试过用adoconnection了,可是提示from子句有问题,我试了用
'select * into aa from bb'
aa和bb都是dbf文件就可以,如果是txt文件时好像有点问题,请指教,谢谢

stjsq (2001-09-30 16:30:00)
经实际测试,用fontain的方法导入同构数据表时速度很快,方法方便,可是导入异构
表时select语句总是出错,不知什么原因,所以还不知效果如何。
用wgzhang的方法导入速度非常快,结合zqs10597249的方法就可以导入不同分隔符的txt
文件到数据库中。
测试数据表类型为dBase数据库,txt文本文件有20000条记录,4个数据字段。
用adotable连ODBC数据库用时:5分钟左右;
用table+BDE别名:3秒;(速度快的有点惊人)
用table+ODBC别名:2分12秒
奇怪的是,用ado速度居然没bde快?

千中元 (2002-06-16 0:39:00)
接受答案了.


fontain的回答最终被接受。
 
楼主的txt文件什么格式?如果规则的话,就用bcp工具,很快的,对应好字段,分隔符,换行符就ok了。不需要读文件
 
不规则,是有选择性的导入的。
 
看楼上的代码看帮助还累[:D]
 
发个样本看看,还有数据库的表
 
接受答案了.
 
后退
顶部