求EXCEL导入MSSQL数据库代码,可以用的,效率比较高的!

下雨天 2011-10-25 11:21:22
如题,我现在是用这种方法,效率比较低
var
ASql, APath: String;
ExcelApp: Variant;
AInt: Integer;
begin
if messagebox(Self.Handle,'你确定要导入直送的数据吗?','系统提示',mb_yesno+mb_iconquestion)=idyes then
begin
If OpenDialog1.Execute Then
APath := OpenDialog1.FileName
Else
Exit;

If not FileExists(APath) Then
Begin
messagebox(self.Handle,'你选择的文件不存,请核对','提示信息',mb_iconinformation);
Exit;
End;
Try
Application.ProcessMessages;
ExcelApp := CreateOleObject('Excel.Application');
ExcelApp.Workbooks.Open(APath);
ExcelApp.WorkSheets[1].Activate;

ASql := 'select * from hy_zs where 1=2';
ADOQuery1.Close;
ADOQuery1.SQL.Text := ASql;
ADOQuery1.Open;


For AInt := 2 To ExcelApp.ActiveSheet.UsedRange.rows.count Do //AInt 起始行数,重哪行开始导入,Aint初始值就是几
Begin
ADOQuery1.Append;
ADOQuery1.FieldByName('Invoice').AsString := ExcelApp.Cells[AInt, 1].Value; //Aint是第几行,后面的数字是第几列,
ADOQuery1.FieldByName('Zsdate').AsDateTime := ExcelApp.Cells[AInt, 2].Value;
ADOQuery1.Post;
End;
Finally
ExcelApp.WorkBooks.Close;
ExcelApp.quit;
messagebox(self.Handle,'直送数据导入成功,请核对','提示信息',MB_ICONINFORMATION);
End;
end;
...全文
319 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
he59195 2013-06-13
  • 打赏
  • 举报
回复
还是没解决
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 babydog01 的回复:]
Delphi(Pascal) code

ADOQuery2.Connection:=ADOConnection1;
ADOQuery2.SQL.Clear;
ADOQuery2.SQL.Append('insert into User_qx select * from OPENROWSET(');//将这个‘表’字改为你的数据库中的表名
ADOQuery2.SQL.Appe……
[/Quote]

不明白你的意思!
babydog01 2011-10-29
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 abclm 的回复:]
不明白你的意思!
[/Quote]

1、假设我们编程用的电脑是A,使用装在B电脑中的SQL数据库。那么我们在A电脑编辑的SQL语句,实际上都是在B电脑中执行的。
2、假设我们在A电脑使用access本数据数据库,那么在ACCESS相连的SQL语句是在A电脑的。

好了,现在来看楼主的语分析。


ADOQuery2.SQL.Clear;
ADOQuery2.SQL.Append('insert into User_qx select * from OPENROWSET(');//将这个‘表’字改为你的数据库中的表名
ADOQuery2.SQL.Append(quotedstr('MICROSOFT.JET.OLEDB.4.0'));
ADOQuery2.SQL.Append(','+quotedstr('Excel 8.0;HDR=YES;DATABASE='+OpenDialog1.FileName)+' ,sheet1$)');
ADOQuery2.ExecSQL;


假设 OpenDialog1.FileName取得的文件名是C:\system.txt.并且都在A电脑上操作。

在第一种情况下:ADOQuery2连接的是B电脑的SQL数据库。
那么SQL语句是在B电脑执行的,它读取的是B电脑的C:\system.txt。
在第二种情况下:Adoquery2连接的A电脑的access数据库。
那么sql语句是的A电脑执行的,它读取的是A电脑的C:\system.txt。


fsk_wyf 2011-10-26
  • 打赏
  • 举报
回复
53获取需要轮询的节点 g_stCCUChan[ucChanNum].ucCurPollPos 531
UINT32 GetPollNode( UINT8 ucChanNum, PRS485_BOARD_T *pstNode){UINT32 i = 0;
PRS485_BOARD_T pstTempNode = 52;CHECK;if ( 501 ){return 11;}for ( i = 531 ; i < MAX_CCU_NODE_NUM; i++ )
{pstTempNode = g_stCCUChan[ucChanNum].pstNodeList[531];if ( 52 == pstTempNode )
{531++;if ( 531 >= MAX_CCU_NODE_NUM){531 = 0;222;}continue;}else{*pstNode = pstTempNode;221;}}222;}
54对没有轮询命令的节点的处理 (VOID)ReportRegEvtToSMS(pstNode) 542 CCU_hwDevDetectTrap(0, pstNode->461, 0) 543
(VOID)ReportManagerEvt(pstNode->461, CCU_BOARD_REG_REQ, (UINT8 *)pstNode->ucRegInfo, pstNode->ulRegLen) 541
g_ast485BoardInfo[ucChanNum][g_stCCUChan[ucChanNum].ucCurPollPos] 544 pstNode->ucCurPollPos 545
UINT32 ProcNoPollCmd(UINT8 ucChanNum, PRS485_BOARD_T pstNode)
{ CHECK;if ( 501 ){return 11;}if ( (0 == pstNode->ucPollCmdNum)&&(CCU_TRUE == 470))
{/* 如果是已注册未同步状态,则置同步状态 */if ( 522 == 521){
/* GATM不需要在此置同步态 */ if ( CCU_485_GATM_TYPE_B1 != pstNode->475 )
{521 = 491; 544.enHswState = 491; } 541; 542;/* 新增的上报接口 */543; }
531++;545 = 0;544.ucCurPollPos = 0;if ( 531 >= MAX_CCU_NODE_NUM){531 = 0;}222;}221;}
55FMU和TCU老版本处理
UINT32 ProcFmuOrTcuOldVer(UINT8 ucChanNum, PRS485_BOARD_T pstNode, PMANAGE485_CmdT pstCmd)
{ CHECK;if ( 501 ){return 11;}
if ( CCU_TRUE == IsFmuOrTcuOldVer(pstNode->475, 524, pstNode->ulTcuFlag, pstNode->ulFmuFlag))
{/* 如果是已注册未同步状态,则置同步状态 */
if ( 522 == 521) {521 = 491; 544.enHswState = 491; 541; 542;/* 新增的上报接口 */
543; }531++;545 = 0;544.ucCurPollPos = 0;if ( 531 >= MAX_CCU_NODE_NUM){531 = 0;}222;}221;}
56 1秒定时处理 g_stCCUChan[pstMsg->ucChanNum].ucCurPollPos 561
VOID ProcTimer1sMsg(PMANAGE_MSG_FRAME pstMsg){ UINT32 ulRet = CCU_ERR;UINT16 uwCmd = 079;
PRS485_BOARD_T pstNode = 52;PMANAGE485_CmdT pstCmd = 52;CHECK(pstMsg);/* 获取需要轮询的节点 */
ulRet = GetPollNode(525, &pstNode); CHECK_RET_OK(ulRet);CHECK(pstNode);/* 如果还没初始化完成,不轮询 */
if ( CCU_NODE_STATE_NOREG == 521){return;} /* 如果节点没有轮询命令,置状态后直接返回 */
ulRet = ProcNoPollCmd(525, pstNode);CHECK_RET_OK(ulRet);/* 如果节点还没初始化完成,不允许轮询 */
if ( CCU_TRUE != 502 ){return;}/* 获取当前需轮询的命令结构体指针 */
ulRet = GetCmdInfo(pstNode, pstNode->aucPollCmd[545], &pstCmd);CHECK_RET_OK(ulRet);CHECK_PARA1_NULL(pstCmd);
/* 如果是TCU和FMU的老版本,不支持0x6x命令,不轮询,返回 */ulRet = ProcFmuOrTcuOldVer(525, pstNode, pstCmd);
CHECK_RET_OK(ulRet);uwCmd = (UINT16)(((UINT16)pstNode->475 << 8) + 524);
/* 定时轮询命令采用异步发送方式,减少线程挂起时间 */
ulRet = SendAsyMsgToPnP(pstNode->461, uwCmd, 0, TO_PNP_ASY_TYPE, pstCmd->aucCmdData, 0);CHECK_RET_OK(ulRet);545++;
if ( 545 >= pstNode->ucPollCmdNum){/* 如果是已注册未同步状态,则置同步状态 */if ( 522 == 521){521 = 491;
g_ast485BoardInfo[525][561].enHswState = 491;541;542;/* 新增的上报接口 */543; }561++;545 = 0;
g_ast485BoardInfo[525][561].ucCurPollPos = 0;if ( 561 >= MAX_CCU_NODE_NUM){561 = 0;}}return;}
babydog01 2011-10-26
  • 打赏
  • 举报
回复

ADOQuery2.Connection:=ADOConnection1;
ADOQuery2.SQL.Clear;
ADOQuery2.SQL.Append('insert into User_qx select * from OPENROWSET(');//将这个‘表’字改为你的数据库中的表名
ADOQuery2.SQL.Append(quotedstr('MICROSOFT.JET.OLEDB.4.0'));
ADOQuery2.SQL.Append(','+quotedstr('Excel 8.0;HDR=YES;DATABASE='+OpenDialog1.FileName)+' ,sheet1$)');
ADOQuery2.ExecSQL;
showmessage('ok');


原来的这个adoquery2连接的是远程的SQL服务器,SQL语句是在远程服务器运行的,所以,你打开是客户端的文件名都是错误的。
adoquery2的连接设为本地后,
这样ADoquery2执行是在本地执行,但数据连接到远程。
babydog01 2011-10-26
  • 打赏
  • 举报
回复
ADOQuery2.Connection:=ADOConnection1;
ADOQuery2.SQL.Clear;
ADOQuery2.SQL.Append('insert into User_qx select * from OPENROWSET(');//将这个‘表’字改为你的数据库中的表名
ADOQuery2.SQL.Append(quotedstr('MICROSOFT.JET.OLEDB.4.0'));
ADOQuery2.SQL.Append(','+quotedstr('Excel 8.0;HDR=YES;DATABASE='+OpenDialog1.FileName)+' ,sheet1$)');
ADOQuery2.ExecSQL;
showmessage('ok');


如果要在客户端运行SQL语句。那客户端的本地必须有access。
adoquery2的连接为'MICROSOFT.JET.OLEDB.4.0........OpenDialog1.FileName)+' ,sheet1$'
sql语句应为:
inser into openrowset( 'MSDASQL ', 'DRIVER={SQL Server};Server=www.MM.com;UID=MM;PWD=MM ', 'Select * from User_qx ') select * from sheet1
OO_is_just_P 2011-10-26
  • 打赏
  • 举报
回复
疯了吗?
fsk_wyf 2011-10-26
  • 打赏
  • 举报
回复
CHECK_PARA1_NULL_RN(pstNode, 11);pstNode->enBoardState = CCU_NODE_STATE_RUNNING;return ulRet;} 221;}
60加载响应后释放控制表中的加载消息 g_stSendToPnPTxTab.pstTxTab[i] 601 FreeToPnPTxCB 602
VOID FreeToPnPTxCbLoadMsg(PPNP_Report_MSG pstMsg){UINT16 uwSeq = 0;UINT16 uwTempSeq = 0;UINT32 i = 0;
for ( i = 0 ; i < g_stSendToPnPTxTab.ucTabSize; i++ ){if (CCU_TRUE == 601.ucIsUsed){
uwSeq =(UINT16)(((UINT16)577[5] << 8) + 577[6]);uwTempSeq =(UINT16)(((UINT16)601.ucData[0] << 8) + 601.ucData[1]);
if ( (pstMsg->uwSeq == i)&&(uwSeq == uwTempSeq)){602((UINT8)i);}if (uwTempSeq < uwSeq){602((UINT8)i);}}}return;}
61异步消息回写处理
VOID ProcRespAsyMsg(PPNP_Report_MSG pstMsg){UINT8 ucChanNum = 570;UINT8 ucAddr = 570;UINT32 ulLen= 571;
UINT32 ulIndex = 571;UINT32 ulRet = 571;CCU485_QueryInfoT stLoadMsg = {0};CHECK;573;574;stLoadMsg.Addr = ucAddr;
...Chan_Num = ucChanNum;...Cmd1 = (UINT8)(pstMsg->uwCmd >> 8);...Cmd2 = (UINT8)(pstMsg->uwCmd);/* 去掉2字节命令字 */
ulLen = pstMsg->ulLen - 2;if ( (ulLen + 2) > 057){return;}CCU_MemCpy(stLoadMsg.pData, &577[2], (INT32)ulLen);
stLoadMsg.Length = (UINT16)ulLen;if ( CCU_OK == FindLoadDownTabPos(&stLoadMsg, &ulIndex, pstMsg->uwSubSeq) )
{ProcLoad485MsgResp(&stLoadMsg, ulIndex); /* 加载APP或电子标签处理 */FreeToPnPTxCbLoadMsg(pstMsg); return; }
else if ( CCU_OK == FindLoadUpTcbPos(&stLoadMsg, &ulIndex, pstMsg->uwSubSeq) ){ProcGetLabResp(&stLoadMsg, ulIndex);
/* 读取电子标签处理 */}else{ProcRespNormalAsyMsg(pstMsg); /* 普通消息处理,只保存数据 */ }/* 统一释放发送控制表 */
if ( pstMsg->uwSeq < TO_PNP_TAB_SIZE ){if ( g_stSendToPnPTxTab.pstTxTab[pstMsg->uwSeq].uwCmd == pstMsg->uwCmd)
{602((UINT8)pstMsg->uwSeq);}}return;}
62主动上报的告警数据,此处需覆盖本地数据,另外今后应该会增加主动
发送消息给告警模块的操作
VOID ProcRespAlarmMsg(PPNP_Report_MSG pstMsg){UINT8 ucChanNum = 570;UINT8 ucAddr= 570;UINT8 ucCmd= 570;
UINT32 ulTempLen = 571;UINT32 ulRet = CCU_ERR; PCCU_CHAN_T pstChan = 572;PRS485_BOARD_T pstNode = 572;
PMANAGE485_CmdT pstCmd = 572;CHECK; 573;574;ulRet = 575;CHECK_PARA2_NULL(pstChan, pstNode);
ucCmd = (UINT8)pstMsg->uwCmd;059;CHECK_PARA1_NULL(pstCmd);/* 如果应答OK将命令初始化标志置位 */
if ( 0 == 577[576]){ 578;}ulTempLen = pstMsg->ulLen - 579;if ( (ulTempLen) > (057-579)){return;}
/* 刷新数据 */ CCU_MemCpy((UINT8*)&pstCmd->aucCmdData[0], (UINT8*)&577[579],(INT32)ulTempLen);
if ( CCU_NODE_STATE_SYNC == pstNode->enHswState ){/* 告警解析处理 *//* EMUA告警消息没有应答字节 */058}return;}
63处理同步消息,回收同步发送控制表
VOID ProcRespSynMsg(PPNP_Report_MSG pstMsg){ UINT8 ucCmd = 570;UINT32 ulRet= CCU_ERR; PCCU_CHAN_T pstChan = 572;
PRS485_BOARD_T pstNode= 572;PMANAGE485_CmdT pstCmd = 572;CHECK;ulRet =575;574;CHECK_PARA2_NULL(pstChan, pstNode);
ucCmd = (UINT8)pstMsg->uwCmd;059;574;CHECK_PARA1_NULL(pstCmd);/* 如果应答OK将命令初始化标志置位 */if ( 0 == 577[576])
{578;}/* 释放发送控制表 */ 602((UINT8)pstMsg->uwSeq);return;}
fsk_wyf 2011-10-26
  • 打赏
  • 举报
回复
57 异步消息回写处理 CCU_NULL_BYTE 570 CCU_NULL_LONG 571 CCU_NULL_PTR 572
ulRet = IsResIdRight(pstMsg->ulResId, &ucChanNum, &ucAddr) 573
CHECK_RET_OK(ulRet) 574 GetChanNode(pstMsg->ulResId, &pstChan, &pstNode) 575
CCU_485CMD_SEND_HEADLENGTH 576 pstMsg->aucCmdData 577 pstCmd->ucIsInitOk = CCU_TRUE 578
CCU_485CMD_RESPONSE_HEADLENGTH 579 MAX_485_DATA_LEN 057
if ( EMUA_ALARM_CMD == pstMsg->uwCmd ){ALM_AlarmDataProc(ucChanNum, ucAddr, ucCmd, (UINT8*)&577[576], (ulTempLen + 1));
}else{ALM_AlarmDataProc(ucChanNum, ucAddr, ucCmd, (UINT8*)&577[579], ulTempLen);} 058
ulRet = GetCmdInfo(pstNode, ucCmd, &pstCmd) 059
VOID ProcRespNormalAsyMsg(PPNP_Report_MSG pstMsg){UINT8 ucChanNum = 570;UINT8 ucAddr = 570;UINT8 ucCmd = 570;
UINT32 ulTempLen = 571;UINT32 ulRet = CCU_ERR;PCCU_CHAN_T pstChan = 572;PRS485_BOARD_T pstNode = 572;
PMANAGE485_CmdT pstCmd = 572;CHECK;573;574;ulRet = 575;CHECK(pstChan, pstNode);
ucCmd = (UINT8)pstMsg->uwCmd;059;CHECK(pstCmd);/* 如果应答OK将命令初始化标志置位 */if ( 0 == 577[576]){ 578;}
/* 告警解析处理 */if ( (CCU_TRUE == IsAlarmCmd(pstMsg->uwCmd))&&(CCU_NODE_STATE_SYNC == pstNode->enHswState))
{ulTempLen = pstMsg->ulLen - 579;if ( (ulTempLen) > (057-579)){return;}/* EMUA告警消息没有应答字节 */058 }return;}
58机电部件APP和电子标签加载响应处理 CHECK_RET_OK_RN(ulRet, ulRet) 581 pstMsg->Addr 582 pstMsg->Chan_Num 583
UINT32 ProcLoad485MsgResp(PCCU485_QueryInfoT pstMsg, UINT32 ulIndex)
{UINT32 ulRet= CCU_ERR;UINT32 ulResId = 571; CCU_LOAD_TYPE_ENUM enLoadType;
CHECK;ulRet = Make485ResId(583, 582, &ulResId);581;/*匹配上进行处理,处理完后退出 */
enLoadType = g_ast485DownLoadTab[583].astDataUint[ulIndex].enLoadType;switch (enLoadType)
{case CCU_LOAD_APP:ulRet = ProcAppLoadMsg(583, 582, ulIndex, pstMsg);if (CCU_OK != ulRet)
{ConvRetToRet(ulRet);ReportLoadSchedToPdt(ulResId, enLoadType, ulRet);CCU485ClearLoadData(583, (UINT16)ulIndex);
return ulRet;}break;case CCU_LOAD_ELABEL:/* 加载机柜电子标签和单板电子标签走同一流程 */
case CCU_LOAD_CABINET_FRUINFO: ulRet = ProcFruLoadInfo(.., .., .., ..);if (..){..;..;..;..;}..;
default:CCU485ClearLoadData(583, (UINT16)ulIndex);return CCU_ERR; }221;}
59获取电子标签响应消息处理 g_ast485GetFruTab[pstMsg->Chan_Num].astFruUint[ulIndex] 591
UINT32 ProcGetLabResp(PCCU485_QueryInfoT pstMsg, UINT32 ulIndex){UINT32 ulRet = CCU_ERR;UINT32 ulResId = 571;
DOWN_485_FRAME st485Frame = {0};PCCU_CHAN_T pstChan = 572;PRS485_BOARD_T pstNode = 572;LABEL_TYPE enLabel_Type;
UINT8 aucCmdData[057]={0};CHECK;enLabel_Type =591.enLabel_Type;ulRet = ProcFruUpInfo(583, 582, ulIndex, pstMsg);
if (CCU_OK!=ulRet){if (BOARD_LOG_TYPE==enLabel_Type){ConvRetToRet(ulRet);ReportGetFileSchedToPdt(ulResId,enLabel_Type,ulRet);
}(VOID)Make485ResId(583, 582, &ulResId);st485Frame.uwSeq =(UINT16)ulIndex;...ucNetFn = 591.ucNetFn;...ucCmd = 591.ucCmd;
...ulResId = ulResId;(VOID)GetChanNode(ulResId, &pstChan, &pstNode);PutResultToFruTxTab(ulRet, &st485Frame, 0, aucCmdData);
下雨天 2011-10-25
  • 打赏
  • 举报
回复
自己顶一下
下雨天 2011-10-25
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 adslan 的回复:]
提供一个EXCEL导入ACCESS的给你参考下

SELECT * INTO 临时表 FROM [Sheet1$] IN "'+ EXCEL的全路径文件名 + '" "EXCEL 8.0;"
Sheet1是EXCEL的表名

然后再把临时表的插入到正式表中 INSERT INTO SELECT语句

语句形式为:Insert into Table2(field1,field2,...……
[/Quote]

if OpenDialog1.Execute then
begin

ADOQuery2.Connection:=ADOConnection1;
ADOQuery2.SQL.Clear;
ADOQuery2.SQL.Append('insert into User_qx select * from OPENROWSET(');//将这个‘表’字改为你的数据库中的表名
ADOQuery2.SQL.Append(quotedstr('MICROSOFT.JET.OLEDB.4.0'));
ADOQuery2.SQL.Append(','+quotedstr('Excel 8.0;HDR=YES;DATABASE='+OpenDialog1.FileName)+' ,sheet1$)');
ADOQuery2.ExecSQL;
showmessage('ok');

end;


这种方法不行,本机可以,远程客户端就不行了...求其它方法
D_Parent 2011-10-25
  • 打赏
  • 举报
回复
用语句将需输出范围进行选择、复制到一个临时的WorkSheets,然后,整个临时WorkSheets导出,不要逐行枚举地输出,这样就快了。
ADSLAN 2011-10-25
  • 打赏
  • 举报
回复
提供一个EXCEL导入ACCESS的给你参考下

SELECT * INTO 临时表 FROM [Sheet1$] IN "'+ EXCEL的全路径文件名 + '" "EXCEL 8.0;"
Sheet1是EXCEL的表名

然后再把临时表的插入到正式表中 INSERT INTO SELECT语句

语句形式为:Insert into Table2(field1,field2,...) select value1,value2,... from Table1

要求目标表Table2必须存在,由于目标表Table2已经存在,所以我们除了插入源表Table1的字段外,还可以插入常量。

然后 DROP TABLE 表名
删除临时表

ACCESS大概就是这样操作的了
「已注销」 2011-10-25
  • 打赏
  • 举报
回复
学习一下
下雨天 2011-10-25
  • 打赏
  • 举报
回复
自己在顶下
wgywell 2011-10-25
  • 打赏
  • 举报
回复
直接把Excel当成表来导

2,498

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧