5,943
社区成员
发帖
与我相关
我的任务
分享procedure TForm1.Button5Click(Sender: TObject);
begin
if FDConnection1.Connected = True then
FDConnection1.Connected := False;
FDConnection1.ConnectionString :=
'ODBCDriver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};' +
'DataSource=.;DriverID=ODBC;CharacterSet=UTF8;Database={D:\202405.xlsx};';
FDConnection1.Connected := True;
if FDConnection2.Connected = True then
FDConnection2.Connected := False;
FDConnection2.ConnectionString :=
'DriverID=MSSQL;Database=xxx;User_Name=sa;Password=xxx;OSAuthent=No;Server=.;';
FDConnection2.Connected := True;
FDBatchMove1的reader和writer设置省略;
FDQuery1.SQL.Add('select 业务量调整,姓名 from [组长考核$]');
FDQuery1.Open();
FDQuery2.SQL.Add('update 绩效计算表 set 业务量调整=:业务量调整 where 姓名=:姓名');
FDQuery2.Params[0].DataType := ftFloat;
FDQuery2.Params[1].DataType := ftString;
FDQuery2.ExecSQL;
FDBatchMoveDataSetReader1.Optimise := False;
FDBatchMoveDataSetWriter1.Optimise := False;
FDBatchMoveDataSetReader1.DataSet := FDQuery1;
FDBatchMoveDataSetWriter1.DataSet := FDQuery2; }
Memo1.Lines.Add('<' + TimeToStr(Now) + '> 共导入 ' + Edit1.Text + ' 记录 ' +
FDBatchMove1.Execute.ToString + ' 条......');
end;
--------------------上面的测试,用 DataSet 就不行,用 SQL 就可以,请教一下,DataSet少了什么?
用 DataSet 提示错误 [FireDAC][Phys][MSSQL]-308. Cannot open / define command, which does not return result sets. Hint: use Execute / ExecSQL method for non-SELECT commands'.
OK,今天终于明白了:
不能使用replace,是因为驱动版本问题,一定要单独使用2010版的access databass,不要用2007,也不要两个都安装。
解决了这个问题,使用sql还是很方便的,就不再瞎鼓捣其他方法了。
就此结贴。
补充:今天又发现了一个奇迹,demo是这么用的:
FDQuery1.SQL.Add('select 业务量调整,姓名 from [考核$]');
FDQuery2.SQL.Add('select 业务量调整,姓名 from 计算表');
FDBatchMoveDataSetReader1.DataSet := FDQuery1;
FDBatchMoveDataSetWriter1.DataSet := FDQuery2;
这样也能修改,都怪我不仔细看例子。
终结语:
研究dataset是为了绕开
FDQuery1.SQL.Add('select 业务量,姓名 from [考核$] where replace(姓名,chr(9),'''') not in ('''')');
中where语句过度使用函数而出现“标准表达式中数据类型不匹配”的错误提示,看来正如 日立奔腾浪潮微软松下联想 大佬所说,ADO太过陈旧了,很多东西有BUG。
测试了dataset在where中使用函数的情况,依然提示相同的错误,看来考虑reader语句的复杂性不太现实,或许方法不对,就此作罢。
如果有哪位大佬清楚在select语句中可以大量使用函数的情况,或者同时使用dataset可以导入excel到mssql的,还请继续赐教,不胜感激。
这次折腾起码知道了reader和writer可以交叉使用,最后可以执行的结果:
FDQuery1.SQL.Add('select 业务量,姓名 from [考核$]');
FDQuery1.Open();
FDBatchMoveSQLWriter1.ReadSQL := 'update 计算表 set 业务量=:业务量 where 姓名=:姓名';
FDBatchMove1.Reader := FDBatchMoveDataSetReader1;
FDBatchMove1.Writer := FDBatchMoveSQLWriter1;
FDBatchMoveSQLWriter1.TableName := '计算表';
FDBatchMove1.GuessFormat();
FDBatchMove1.Execute;
仔细的看了看帮助文件,似乎三种模式可以混用?
尝试了
FDBatchMove1.Reader := FDBatchMoveDataSetReader1;
FDBatchMove1.Writer := FDBatchMoveSQLWriter1;
竟然可以了,似懂非懂。
看来dataset之间的move应该是一个server才可以,是不是用dataset不能直接move外部的excel表和mssql?
难道和这个有关系,excel导入mssql不支持?
小猴子这敬业精神,要拿多少年终奖啊~~~
两种方式不对等,前者用FDBatchMoveDataSetWriter,后者用FDBatchMoveSQLWriter
按照EMB的说明:https://docwiki.embarcadero.com/Libraries/Sydney/en/FireDAC.Comp.BatchMove.SQL.TFDBatchMoveSQLWriter
Note: You cannot use the TableName property and the ReadSQL property at the same time.
所以这两句:
FDBatchMoveSQLWriter1.ReadSQL := 'update 计算表 set 业务量=:业务量 where 姓名=:姓名';
FDBatchMoveSQLWriter1.TableName := '计算表';
应该只有后设置的TableName起作用,也就是写数据集是TableName那个表,不是ReadSQL返回的数据集(所以这个返不返回数据集都无所谓了)
而前者的FDQuery2.ExecSQL;不返回数据集
后面的
FDBatchMoveDataSetWriter1.DataSet := FDQuery2;
必然出错。
头疼,先睡觉了