如何把纯文本文件导入到SQL SERVER数据库的表中

时间:2022-09-19 22:31:28
我想把一个纯文本文件导入到SQL SERVER数据库的test表中,文本文件的格式与test表的个列对应是规则的,各个字段间用空格分开的!!
请教各位我该如何实现??

24 个解决方案

#1


bcp test in test.txt -c -t  -Uname -Ppass -Sserver

#2


我以前做过,是用存储过程,但系统负担太重!

#3


我的老师确实说过要我用存储过程,可是我还不是很清楚该如何处理!!!

#4


手工一步一步来不行么?

#5


vickly你好,我想知道你还能不能帮我做一下呀??我有急用的!!

ujs你好,我实在是太菜了,我连enterprise manager都没有找到呢!!:(

#6


你要我怎么帮你呢?
要我发程序给你吗?

#7


给你一个例子吧
例如,有一段人事档案资料archive.txt,内容如下:
  小许男21工程师
  小吴女23助理工程师
  小蔡男22助理工程师
  小牟女22工程师
要将它转入数据库archive.dbf中,archive.dbf结构如下:
  姓名,性别,年龄,职称
怎么办呢?现在通过使用delphi编程,很好地解决了这个难题。Delphi提供了许多功能强大,丰富的字符处理函数和过程,常用的有:
  (1)functionLength(S:String):Integer
  //返回串的长度
  (2)functionCopy(S:String;Index,Count:Integer):String
  //给出一个字符串中串的拷贝
  (3)functionPos(Substr:String;S:String);Integer
  //查找子串在字符串中的位置
  (4)ProcedureDelete(VarS:String;Index,Count:Integer);
  //从一个字符串中去除子串
  利用Delphi提供的已有函数和过程基础上编制自己的三个函数,实现了纯文本格式资料转入数据库功能。只要Delphi支持的数据库都可以支持。
  archive.txt中每行数据为一个字符串,字符串中每个被分割的数据为一个字段,分割每个字段的字符为分割符,这里是空格,也可以是,、;、#等符号。具体思想
是:先将字符串进行调整,然后把串中每个字符同分割符比较,将不是分割符的字符追加到MyStr串中,最后得到一个字段的内容。通过一个循环,就可以将一个字符串分
成几个字段。
  FunctionRegulate(aString,Sepchar:string):string
  //去掉多余的分割符,规范字符串
  FunctionGetSubStr(varsString:string;SepChar:String):String;
  //得到字符串中一个子串
  //因要改变参数aString的值,所以将它用var定义。
  FunctionGetSubStrNum(aString,SepChar:String):Integer;
  //计算一个字符串要被分割成几个字段。
  参数:aString是所需分割的一个字符串,SepChar是分割符。
  FunctionRegulateStr(aString:String;Sepchar:String):String;
  var
  i,Num:Integer;
  Flag:Boolean;
  MyStr,TempStr:String;
  begin
  Flag:=False;//进行标志,去除多余的分割符
  Num:=Length(aString);//计算aString串的长度
  fori:=1toNumdo
  begin
  TempStr:=Copy(aString,i,1);//取aString串中的一字符
  if TempSt>=SepChar then
  begin
  MyStr:=MyStr+TempDtr;
  Flag:=True;
  end
  else
  if(Flag=True)then
  begin
  Mystr:=Mystr+TempSrt;
  Flag:=False;
  end;
  end;
  if MyStr[Length(MyStr)]>=SepChar then
  MyStr:=MyStr+SepChar;
  RegulateSrt:=MyStr;
  end;
  FunctionGetSubStr(varaString:String,SepChar:Strign):String;
  var
  Mysrt:String;
  StrLen:Integer;
  SepCharPso:Integer;
  begin
  StrLen:=Length(aString);
  SepCharPos:=Pos(SepChar,aString);//计算分割符在子串中的位置
  MyStr:=Copy(aString,1,SepCharPos-1);//将分割符前所有字符放到mystr串中
  Delete(aString,1,SepCharPos);//除去分割符和分割符前的子串
  GetSubStr:=MyStr;//返回一个字段
  end;
  FunctionTforml.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;
  GetSubSrtNum:=Num;
  end:
  有了上面三个函数,现在介绍一下具体的应用:
  1.首先建立一个窗体Forml,加入一个RichEditl(或Menol),一个按钮Buttonl和一个Tablel,设置Tablel的属性:
  Tablell.DataBase=′c:Archivs′
  Tablell.TableName=′Archive.dbf′
  2.分别加入以下程序:
  ConstSpace:=′′
  ProcedureTForml.FormCreate(Sender:Tobject);
  begin
  RichRditl.Lines.LoadFromFile(′Archive.txt′);
  end;
  ProcedureTForml.Button1Click(Sender:T object);
  var
  i,j:Integer;
  MyLine:String;
  begin
  with Tablel do
  begin
  Open;
  for i:=0 to RichEditl.Lines.Count-1 do
  begin
  MyLine:=RegulateStr(Richeditl.Lines[i],Space);
  for  j:=1 to Num To ken(MyLIne,Space) do
  begin
  Append;
  fileds[j-1].aString:=GetSubSrt(MyLine,Space));
  post;
  end;
  end;
  end;
  end; 

#8


to  fuction(我是东北那旮来地) 
是你做的么?真佩服

#9


fuction谢谢你的例子,我知道这个例子
我现在正在调试这个程序,因为这个例子好象还不完善!!

#10


vickly,
如果可以的话我当然希望你发给我了!!

我的邮箱lanlemon04272@sohu.com

#11


vickly 不好意思我上面的邮箱写错了,应该是lanlemon0427@sohu.com  :P

#12


agree newwen,use bcp package

#13


收邮件!!
写得不太好,将就点!!那是我刚学Delphi时写的:)

#14


vickly:
谢谢你的邮件,我已经收到了,非常感谢!!

#15


请给我发一份好吗?menglica@163.com,谢谢!

#16


我的解决办法:文件放在服务器上,知道存放径及文件名后。delphi支持
with query1 do
 begin  
  close;  
  sql.clear;  
  sql.add('BULK INSERT au..mengzi FROM ''d:\tb\mengzi.txt''');
  execsql;
 end;
mengzi可由sqlserver数据导入功能将文本文件存入库中,然后将数据删除成为空表

#17


mengli1:
将哪里的数据删除啊???

#18


用DTS吧

#19


我做了两个过程
我是字段之间以Tab为分格的

数据库到txt
procedure TForm_main.DBToTxt(SourceTable:TTABLE;Txtname:TFileName);
var
  tmptxt:tstringlist;
  i:integer;
  TmpStr:string;
begin
  try
    tmptxt:=tstringlist.create;
    with Sourcetable do begin
      while not eof do begin
        tmpstr:='';
        for i:=0 to fieldcount-1 do
          tmpstr:=tmpStr+fields[i].AsString+#9;    //#9 is tab
        tmptxt.add(tmpstr);
        next;
      end;
    end;
    tmptxt.add(#26);     //#26 is end
    tmptxt.savetofile(txtname);
  finally
    tmptxt.Free;
  end;
end;  

txt去数据库
procedure TForm_main.TxtToDB(SourceTable:TTable;Txtname:TFileName);
var
  F1:Textfile;
  i,j:integer;
  TmpStr,TmpTag,templineno:string;
  ch:char;
begin
  try
    AssignFile(F1,txtname);
    reset(f1);
    read(f1,ch);
    while ch<>#26 do begin
      if not SourceTable.Active then SourceTable.Open;
      SourceTable.Append;
      for i:=0 to SourceTable.FieldCount-1 do begin
        TmpStr:='';
        while (ch<>#9) do begin     //#9 is tab
          if ch<>#13 then  begin     //#13 is enter
            if ch<>#26 then begin    //#26 is end
              Tmpstr:=TmpStr+ch;
              read(F1,ch);
            end else begin
               closefile(f1);
               //showmessage('ok');
               exit;
            end;
          end else
            read(f1,ch);
        end;
        read(F1,ch);

         SourceTable.Fields[i].AsString:=trim(TmpStr);
        
      end;//end of (for i:=0 to SourceTable.FieldCount-1 do)
    end;//end of (if not eof(f1) then
  except
    closefile(f1);
    MessageDlg( '接收数据失败!',mtError,[mbOk],0);
  end;
end;

#20


用DTS的话几分钟就搞定了啊

你点开始——>点程序->点microsoft sql server->点企业管理器->

工具->数据倒入->点下一步->在数据源的地方选择文本文件-》点下一步直接完成

就OK;饿啊

#21


我说的是先创建一个字段数量、类型与文本文件中字段数量、类型完全一样的空表,例如程序中的MENGZI表。
   已通过测试,确实可在DELPHI中控制将存放在服务器上的文本文件导入库中,只试验了文件中字段以空格隔离的情况,其余未测。
   不知道对你有没有启示?

#22


mengli1:
  那你有没有试验过把非服务器上的txt文件导入服务器上的数据库中呢??

#23


用BDE或ODBC都可以实现
ODBC
定义一个dsn,选择microsoft text driver,选择目录,定义格式,然后一切ok;
BDE 中需要定义一个访问的配置文件;
能够连接到text然后对他进行导入就是很容易的事了

#24


vickly:
   我要在SQL SERVER服务器上建立我要用到的存储过程,其中test是接收文本文件的数据表,初始为空,而且这个表中只有date,chanel,value三个字段,不知道我下面的存储过程写的对不对,请给我指点一下:
CREATE PROCEDURE insertinfo(@date datetime,@chanel smallint,@value real)
AS
begin
  insert test
         (date,chanel,value) 
  values(@date,@chanel,@value)
end;

#1


bcp test in test.txt -c -t  -Uname -Ppass -Sserver

#2


我以前做过,是用存储过程,但系统负担太重!

#3


我的老师确实说过要我用存储过程,可是我还不是很清楚该如何处理!!!

#4


手工一步一步来不行么?

#5


vickly你好,我想知道你还能不能帮我做一下呀??我有急用的!!

ujs你好,我实在是太菜了,我连enterprise manager都没有找到呢!!:(

#6


你要我怎么帮你呢?
要我发程序给你吗?

#7


给你一个例子吧
例如,有一段人事档案资料archive.txt,内容如下:
  小许男21工程师
  小吴女23助理工程师
  小蔡男22助理工程师
  小牟女22工程师
要将它转入数据库archive.dbf中,archive.dbf结构如下:
  姓名,性别,年龄,职称
怎么办呢?现在通过使用delphi编程,很好地解决了这个难题。Delphi提供了许多功能强大,丰富的字符处理函数和过程,常用的有:
  (1)functionLength(S:String):Integer
  //返回串的长度
  (2)functionCopy(S:String;Index,Count:Integer):String
  //给出一个字符串中串的拷贝
  (3)functionPos(Substr:String;S:String);Integer
  //查找子串在字符串中的位置
  (4)ProcedureDelete(VarS:String;Index,Count:Integer);
  //从一个字符串中去除子串
  利用Delphi提供的已有函数和过程基础上编制自己的三个函数,实现了纯文本格式资料转入数据库功能。只要Delphi支持的数据库都可以支持。
  archive.txt中每行数据为一个字符串,字符串中每个被分割的数据为一个字段,分割每个字段的字符为分割符,这里是空格,也可以是,、;、#等符号。具体思想
是:先将字符串进行调整,然后把串中每个字符同分割符比较,将不是分割符的字符追加到MyStr串中,最后得到一个字段的内容。通过一个循环,就可以将一个字符串分
成几个字段。
  FunctionRegulate(aString,Sepchar:string):string
  //去掉多余的分割符,规范字符串
  FunctionGetSubStr(varsString:string;SepChar:String):String;
  //得到字符串中一个子串
  //因要改变参数aString的值,所以将它用var定义。
  FunctionGetSubStrNum(aString,SepChar:String):Integer;
  //计算一个字符串要被分割成几个字段。
  参数:aString是所需分割的一个字符串,SepChar是分割符。
  FunctionRegulateStr(aString:String;Sepchar:String):String;
  var
  i,Num:Integer;
  Flag:Boolean;
  MyStr,TempStr:String;
  begin
  Flag:=False;//进行标志,去除多余的分割符
  Num:=Length(aString);//计算aString串的长度
  fori:=1toNumdo
  begin
  TempStr:=Copy(aString,i,1);//取aString串中的一字符
  if TempSt>=SepChar then
  begin
  MyStr:=MyStr+TempDtr;
  Flag:=True;
  end
  else
  if(Flag=True)then
  begin
  Mystr:=Mystr+TempSrt;
  Flag:=False;
  end;
  end;
  if MyStr[Length(MyStr)]>=SepChar then
  MyStr:=MyStr+SepChar;
  RegulateSrt:=MyStr;
  end;
  FunctionGetSubStr(varaString:String,SepChar:Strign):String;
  var
  Mysrt:String;
  StrLen:Integer;
  SepCharPso:Integer;
  begin
  StrLen:=Length(aString);
  SepCharPos:=Pos(SepChar,aString);//计算分割符在子串中的位置
  MyStr:=Copy(aString,1,SepCharPos-1);//将分割符前所有字符放到mystr串中
  Delete(aString,1,SepCharPos);//除去分割符和分割符前的子串
  GetSubStr:=MyStr;//返回一个字段
  end;
  FunctionTforml.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;
  GetSubSrtNum:=Num;
  end:
  有了上面三个函数,现在介绍一下具体的应用:
  1.首先建立一个窗体Forml,加入一个RichEditl(或Menol),一个按钮Buttonl和一个Tablel,设置Tablel的属性:
  Tablell.DataBase=′c:Archivs′
  Tablell.TableName=′Archive.dbf′
  2.分别加入以下程序:
  ConstSpace:=′′
  ProcedureTForml.FormCreate(Sender:Tobject);
  begin
  RichRditl.Lines.LoadFromFile(′Archive.txt′);
  end;
  ProcedureTForml.Button1Click(Sender:T object);
  var
  i,j:Integer;
  MyLine:String;
  begin
  with Tablel do
  begin
  Open;
  for i:=0 to RichEditl.Lines.Count-1 do
  begin
  MyLine:=RegulateStr(Richeditl.Lines[i],Space);
  for  j:=1 to Num To ken(MyLIne,Space) do
  begin
  Append;
  fileds[j-1].aString:=GetSubSrt(MyLine,Space));
  post;
  end;
  end;
  end;
  end; 

#8


to  fuction(我是东北那旮来地) 
是你做的么?真佩服

#9


fuction谢谢你的例子,我知道这个例子
我现在正在调试这个程序,因为这个例子好象还不完善!!

#10


vickly,
如果可以的话我当然希望你发给我了!!

我的邮箱lanlemon04272@sohu.com

#11


vickly 不好意思我上面的邮箱写错了,应该是lanlemon0427@sohu.com  :P

#12


agree newwen,use bcp package

#13


收邮件!!
写得不太好,将就点!!那是我刚学Delphi时写的:)

#14


vickly:
谢谢你的邮件,我已经收到了,非常感谢!!

#15


请给我发一份好吗?menglica@163.com,谢谢!

#16


我的解决办法:文件放在服务器上,知道存放径及文件名后。delphi支持
with query1 do
 begin  
  close;  
  sql.clear;  
  sql.add('BULK INSERT au..mengzi FROM ''d:\tb\mengzi.txt''');
  execsql;
 end;
mengzi可由sqlserver数据导入功能将文本文件存入库中,然后将数据删除成为空表

#17


mengli1:
将哪里的数据删除啊???

#18


用DTS吧

#19


我做了两个过程
我是字段之间以Tab为分格的

数据库到txt
procedure TForm_main.DBToTxt(SourceTable:TTABLE;Txtname:TFileName);
var
  tmptxt:tstringlist;
  i:integer;
  TmpStr:string;
begin
  try
    tmptxt:=tstringlist.create;
    with Sourcetable do begin
      while not eof do begin
        tmpstr:='';
        for i:=0 to fieldcount-1 do
          tmpstr:=tmpStr+fields[i].AsString+#9;    //#9 is tab
        tmptxt.add(tmpstr);
        next;
      end;
    end;
    tmptxt.add(#26);     //#26 is end
    tmptxt.savetofile(txtname);
  finally
    tmptxt.Free;
  end;
end;  

txt去数据库
procedure TForm_main.TxtToDB(SourceTable:TTable;Txtname:TFileName);
var
  F1:Textfile;
  i,j:integer;
  TmpStr,TmpTag,templineno:string;
  ch:char;
begin
  try
    AssignFile(F1,txtname);
    reset(f1);
    read(f1,ch);
    while ch<>#26 do begin
      if not SourceTable.Active then SourceTable.Open;
      SourceTable.Append;
      for i:=0 to SourceTable.FieldCount-1 do begin
        TmpStr:='';
        while (ch<>#9) do begin     //#9 is tab
          if ch<>#13 then  begin     //#13 is enter
            if ch<>#26 then begin    //#26 is end
              Tmpstr:=TmpStr+ch;
              read(F1,ch);
            end else begin
               closefile(f1);
               //showmessage('ok');
               exit;
            end;
          end else
            read(f1,ch);
        end;
        read(F1,ch);

         SourceTable.Fields[i].AsString:=trim(TmpStr);
        
      end;//end of (for i:=0 to SourceTable.FieldCount-1 do)
    end;//end of (if not eof(f1) then
  except
    closefile(f1);
    MessageDlg( '接收数据失败!',mtError,[mbOk],0);
  end;
end;

#20


用DTS的话几分钟就搞定了啊

你点开始——>点程序->点microsoft sql server->点企业管理器->

工具->数据倒入->点下一步->在数据源的地方选择文本文件-》点下一步直接完成

就OK;饿啊

#21


我说的是先创建一个字段数量、类型与文本文件中字段数量、类型完全一样的空表,例如程序中的MENGZI表。
   已通过测试,确实可在DELPHI中控制将存放在服务器上的文本文件导入库中,只试验了文件中字段以空格隔离的情况,其余未测。
   不知道对你有没有启示?

#22


mengli1:
  那你有没有试验过把非服务器上的txt文件导入服务器上的数据库中呢??

#23


用BDE或ODBC都可以实现
ODBC
定义一个dsn,选择microsoft text driver,选择目录,定义格式,然后一切ok;
BDE 中需要定义一个访问的配置文件;
能够连接到text然后对他进行导入就是很容易的事了

#24


vickly:
   我要在SQL SERVER服务器上建立我要用到的存储过程,其中test是接收文本文件的数据表,初始为空,而且这个表中只有date,chanel,value三个字段,不知道我下面的存储过程写的对不对,请给我指点一下:
CREATE PROCEDURE insertinfo(@date datetime,@chanel smallint,@value real)
AS
begin
  insert test
         (date,chanel,value) 
  values(@date,@chanel,@value)
end;