怎样把本地dbf数据导入到远程SQL服务器上 ( 积分: 200 )

  • 主题发起人 主题发起人 kingsonchan
  • 开始时间 开始时间
K

kingsonchan

Unregistered / Unconfirmed
GUEST, unregistred user!
客户端有1dbf文件,文件名会改变的,路径不变。
现想用一句sql之类的代码直接把dbf导入到远程的sql里。
查过一些资料,如用连接串,用OpenDataSource,总是有问题,只能处理文件在服务器里的情况。究竟怎样才可以达到这个效果,让导入的速度足够快呢?
 
呵呵我是这样做的在服务器上做个定时程序。把远程DBF文件复制到服务器上(delphi把复制命令写到bat文件,在掉用).在用在写个存储过程利用opendataset来导入到表。本来想直接用opendataset的但是不支持远程路径。所以想得这个办法。我导入4,5个表最大的表里有1万多条记录。
 
不能复制上去啊,一来不允许,二来也不会为了一个问题而制造另一个问题吧。
 
在SQLServer中执行
SELECT * into bmk
FROM OpenDataSource( 'Microsoft.Jet.OLEDB.4.0',
'Data Source="e:/share";User ID=Admin;Password=;Extended properties=dBase 5.0')...bmk
这样就可以把e:/share中的bmk.dbf表导入到Sqlserver中,
速度是最快的
上面这个方法DBF文件必须在服务器上,如果DBF不在服务器上,就用
连接串
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:/temp;Extended Properties="dBase 5.0;";Persist Security Info=False
SQL语句
SELECT * into aaa IN [ODBC]
[ODBC;Driver=SQL Server;UID=sa;PWD=;Server=127.0.0.1;DataBase=Demo;]
from aaa
这是直接把客户端上的DBF传上服务器的最直接方法。

我没试过,你正好可以试试
 
这个方法我看过啦,网上大把大把的不行啊。也许是我水平不够,请高人指点,说得清楚些。
 
我说过那个不支持网络路径。我试了的。我的客户不需要时时性所以我可以每天晚上23点设置成自动导。反正发法有多种我只提供一种解决办法。
 
我也很想知道这个问题是怎么解决的,
 
给你段我程序里面拷贝出来的代码,肯定能用,
Function UpdateTable(DBFFileName:String):Boolean;
const
SqlProvider = 'Provider=Microsoft.Jet.OLEDB.4.0;'+
'Data Source=%S;'+
'Extended Properties=dBase 5.0;'+
'Persist Security Info=False';
AppendSql = 'SELECT * Into Code_CMCODE IN %S From %S'; //表名自己到时更改一下
var tpFileName,tpPath, tpsql:String;
tpForm:TForm;
tpConn:TADOConnection;
begin
Result:=False;
//开始更新文件
tpFileName:=DBFFileName;
tpPath:=ExtractFilePath(tpFileName);
if StrIsEnd('/',tpPath) then
Delete(tpPath, length(tpPath), 1);
tpFileName:= ExtractFileName(tpFileName);
if CountStrTimes('.',tpFileName) = 2 then //这两句是取文件名字,不
tpFileName := GetAppointStr('.', tpFileName, 1); //带扩展名的函数,自已用COPY,POS函数重写一下即可。实现的功能就是去掉文件扩展名

if StrIsEmpty(tpFileName) or StrIsEmpty(tpPath) then
Abort;

try
tpConn:=TADoConnection.Create(nil);
try
tpConn.LoginPrompt := False;
tpConn.ConnectionString:=Format(SqlProvider,[tpPath]);
tpSql := GetConn(utConn); //这是一个将连接SQL服务器的串,转换成连接DBF串的函数,见后面。参数只要给一个ADO连接SQL的ADOCONNECTION对象就可以了。
tpSql := Format(AppendSql, [tpSql, tpFileName]);
tpConn.Execute(tpSql);
Finally
tpConn.Free;
end;
end;

Function GetConn(Conn:TADOConnection):String;
var ConnStr,tpRtn, tpStr:String;
tpConn: TStrings;
begin
ConnStr:=Conn.ConnectionString;
tpRtn:=ConnStr+';';
try
tpConn:=TStringList.Create;
while Length(Trim(tpRtn))>0 do begin
tpConn.Add(copy(tpRtn,1,pos(';',tpRtn)-1));
delete(tpRtn,1,pos(';',tpRtn));
end;
tpRtn:='[ODBC] [ODBC;Driver=SQL Server;UID=';
tpStr:=tpConn.Values['User ID'];
tpRtn:=tpRtn+tpStr+';PWD=';
tpStr:=tpConn.Values['Password'];
tpRtn:=tpRtn+tpStr+';Server=';
tpStr:=tpConn.Values['Data Source'];
tpRtn:=tpRtn+tpStr+';DataBase=';
tpStr:=tpConn.Values['Initial Catalog'];
tpRtn:=tpRtn+tpStr+';]';
finally
tpConn.Free;
end;
Result:=tpRtn;
End;

上面这个功能我已经用了很多了,追加几万条的记录都未出错过,关键有一点需要注意的就是,如果DBF是VFP高于2.X版本的数据库表,那么需要转换成 2.X才能执行,否则会报文件格式错, 方法就是安装一个VFP,然后打开待升级的文件,运行一下
COPY TO XXXX.DBF FOX2X
就可以了。
其他的类似用vfpoledb.dll来提供对OLE连接的支持了,或者OPENSOURCE等,都不是很好,只有这种方法是最快最稳定的。
 
最近忙了些,没及时回复,不好意思。
很好啊,levi的代码是有效的,但有个问题就是,我的表已经建好,怎样直接把记录添加到表中?如果把
AppendSql = 'SELECT * Into Code_CMCODE IN %S From %S';
改成
AppendSql = 'insert Into Code_CMCODE IN %S select * From %S';
会提示select into错误。
 
再次尝试了各种情况,总结一下:
1。[ODBC]连接是可以的,但要提供用户名和密码,用Windows验证的话会会出错。
2。insert into 是可以的。
3。发现一个问题,就是当要插入的表是临时表时,就会提示insert into语法错误,不用临时表就一切正常。希望levi帮忙解决一下。
 
临时表的表名由于用到了符号##,所以在ADO里是通不过的,这个我也没什么办法。
只能在之前想一个临时的正式表名,然后先添加到SQL 2000正式表里面(表名可以是临时的表名啊),最之后你可以通过存储过程或者什么方法,把数据追加到临时表上就可以了。当然这会牺牲一点时间了。或者只接把表当作临时表用也可以啊,两者区别无非是一个重启自动清除,另一个要手动删除而已。
 
是ADO的原因吗?我用ADO创建临时表是可以的啊,就是连接DBF的那个ADO,用##号就有问题。
 
你说连接 DBF? DBF本身就不支持什么临时表,他的表名只能是严格按照以字母或下划线打头,字母数字作为名字的。
也就是说 Microsoft.Jet.OLEDB.4.0的驱动,在扩展属性是Extended Properties=dBase 5.0后,就不可能支持##的临时表了,
 
多人接受答案了。
 
结帖了,多谢levi的解答和大家的参与。
那我只好自己drop table了,如果大家还有好提议要说出来啊。
 
后退
顶部