用For循环处理数据,然后插入数据,为什么数据会被插入两次?

山的那边还是山~ 2009-06-02 09:46:15
具体过程是这样的,在循环里头处理数据,处理后把这些处理的数据插入数据库。该过程是启动了一个线程进行的。
问题是,每一次循环把这些处理的数据插入了两次数据库,就是每一条记录都重复了一次。

从程序控制上说,For循环是多少次,这个没有错的,但是为什么会每一次循环运行了两次,也或者是数据库服务器的问题。

用的数据库是2005,数据库操作用的是ADO。
...全文
715 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
等不到来世 2009-06-02
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 cftxlin 的回复:]
引用 14 楼 szx1999 的回复:
引用 13 楼 cftxlin 的回复:
回复11,12楼的朋友:

不会的,在处理完一条数据后,会修改数据库中的标志,那么在下一次运行时,就不会再取到该条数据了。
问题是:程序是正确运行一段时间,就会出现这个问题。而且把程序重新启动一次,这种现象会暂且消失。
而且在插入的表里头,没有触发器。

这个问题应该是比较好调试的,
在关键处设置断点跟一下,看一些标识数据是否如你所愿。

[/Quote]
可能是网络或硬件等原因,导致插入事件重复提交。
可修改插入的存储过程,在插入前判断一下是否有重复数据或插入后判断回滚。
  • 打赏
  • 举报
回复
还有一个问题在我的日志里头,记录有两次写数据库的时间,这个时间几乎相同,就差几个,几十个毫秒。
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 szx1999 的回复:]
引用 13 楼 cftxlin 的回复:
回复11,12楼的朋友:

不会的,在处理完一条数据后,会修改数据库中的标志,那么在下一次运行时,就不会再取到该条数据了。
问题是:程序是正确运行一段时间,就会出现这个问题。而且把程序重新启动一次,这种现象会暂且消失。
而且在插入的表里头,没有触发器。

这个问题应该是比较好调试的,
在关键处设置断点跟一下,看一些标识数据是否如你所愿。
[/Quote]

这个是服务程序,关键问题是怎么调试都不会出现我上面所说的问题,可是到了客户那里,运行半月,五天时间,然后它就出事,就出现重复的单子,快整死我了都。
等不到来世 2009-06-02
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 cftxlin 的回复:]
回复11,12楼的朋友:

不会的,在处理完一条数据后,会修改数据库中的标志,那么在下一次运行时,就不会再取到该条数据了。
问题是:程序是正确运行一段时间,就会出现这个问题。而且把程序重新启动一次,这种现象会暂且消失。
而且在插入的表里头,没有触发器。
[/Quote]
这个问题应该是比较好调试的,
在关键处设置断点跟一下,看一些标识数据是否如你所愿。
  • 打赏
  • 举报
回复
回复11,12楼的朋友:

不会的,在处理完一条数据后,会修改数据库中的标志,那么在下一次运行时,就不会再取到该条数据了。
问题是:程序是正确运行一段时间,就会出现这个问题。而且把程序重新启动一次,这种现象会暂且消失。
而且在插入的表里头,没有触发器。
sdhdy 2009-06-02
  • 打赏
  • 举报
回复
首先,看看你插入数据的表里有没有触发器,确定完这个再说。
等不到来世 2009-06-02
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 cftxlin 的回复:]
我所说的for循环,指的是:

C/C++ codefor (i = 0; i < lRecordCount; ++i)
[/Quote]
外面还有个循环:
while (CDataProcDlg::m_staticIsStop)


不知道会不会让你的for循环执行两次呢
  • 打赏
  • 举报
回复
我所说的for循环,指的是:
for (i = 0; i < lRecordCount; ++i)
brio8425 2009-06-02
  • 打赏
  • 举报
回复
为什么要在循环中插入数据库呢、、、

不能在数据库中循环么。?把字符组合起来在数据库中分拆在插入不是更好么。!~
  • 打赏
  • 举报
回复
UINT myProcessDataProc(LPVOID lpvoid)
{
CADOCftlin dbProcess, dbCheck;
string strDBLocale = "local.ini";
dbProcess.SetConfigFile(strDBLocale);
dbCheck.SetConfigFile(strDBLocale);
//dbProcess.OpenDatabase();
//dbCheck.OpenDatabase();

string strID, strGlideID, strPackData, strTmp;

//CString strSql;
CDataProcDlg *dlg = (CDataProcDlg *)AfxGetMainWnd();
long lRecordCount = 0;
int i = 0, iRecordNum = 0, k = 0;

STR_ODRECORD odrecord[120];
char* recorddata[120];
char* recordtemp;
char* temptable;
char szPackData[1024] = { 0 };

AfxOleInit();

gThreadIsExit2 = 0;
CButton *btn = (CButton *)(dlg->GetDlgItem(IDOK));
btn->EnableWindow(FALSE);

while (CDataProcDlg::m_staticIsStop)
{
//if (!dbCheck.IsConnected())
dbCheck.OpenDatabase();
//if (!dbProcess.IsConnected())
dbProcess.OpenDatabase();

lRecordCount = 0;
if (dbProcess.GetPackData()) //执行获取数据的存储过程
lRecordCount = dbProcess.GetRecordCount();
else
{
Sleep(60000);
continue;
}

for (i = 0; i < lRecordCount; ++i)
{
DWORD countStart = 0;
countStart = GetTickCount();

dbProcess.GetFieldValue(0, strID);
dbProcess.GetFieldValue(1, strGlideID);
dbProcess.GetFieldValue(2, strPackData);

memset(szPackData, 0, sizeof(szPackData));
strcpy(szPackData, strPackData.c_str());
//AfxMessageBox(szPackData);
recordtemp = strtok(szPackData, "#");

iRecordNum = 0;
while(recordtemp) //拆成多个包
{
recorddata[iRecordNum] = recordtemp;
iRecordNum++;
recordtemp = strtok(NULL, "#");
}

if (iRecordNum == 0)
{
dbProcess.MoveRecordNext();
continue;
}

for(k = 0; k < iRecordNum; ++k) //把拆分到的数据保存在结构str_GDINFO中
{
memset(&odrecord[k], '\0', sizeof(STR_ODRECORD));

strcpy(odrecord[k].glideID, strGlideID.c_str());

temptable = strtok(recorddata[k], "|");
if(temptable != NULL)
strcpy(odrecord[k].GDID, temptable);

temptable = strtok(NULL, "|");
if(temptable != NULL)
strcpy(odrecord[k].num, temptable);
}

int iReturnVal = dbProcess.AddData(odrecord, iRecordNum, countStart); //, strID

//strSql.Format(strSqlUpdate, strID.c_str());
//strTmp = strSql;
//dbProcess.ExecuteJustSql(strSql.GetBuffer(0));
//writeLog(strTmp);
//strSql.ReleaseBuffer();

if (iReturnVal == iRecordNum)
{
CString strSql, strTmp;
int iLinTag = 0;
string strExe, strField1 = "0", strField2 = "0";
long lCount = 0;
strTmp = "select tagFinished from packData where glideID = '%s'";
CString strSqlUpdate = "update packData set tagFinished = 1 where ID = %s";

strSql.Format(strSqlUpdate, strID.c_str());
strExe = strSql;
dbCheck.ExecuteJustSql(strExe);
//writeLog(strExe);

strSql.Format(strTmp, strGlideID.c_str());
strExe = strSql;
dbCheck.ExecuteSqlWithRecordSet(strExe);
//writeLog(strExe);
lCount = dbCheck.GetRecordCount();

string *strResult = new string[lCount];

iLinTag = 1;
for (k = 0; k < lCount; ++k)
{
dbCheck.GetFieldValue(0, strResult[k]);

if (strResult[k] != "1")
{
iLinTag = 0;
break;
}

dbCheck.MoveRecordNext();
}

delete [] strResult;

/*
if (lCount == 1)
{
dbCheck.GetFieldValue(0, strField1);
if (strField1 == "1")
iLinTag = 1;
}
else if (lCount == 2)
{
dbCheck.GetFieldValue(0, strField1);
dbCheck.MoveRecordNext();
dbCheck.GetFieldValue(0, strField2);

if (strField1 == "1" && strField2 == "1")
iLinTag = 1;
}
else
{
iLinTag = 0;
}
*/

strTmp = "update odrecord_Main set Finished = 1 where odid = '%s'";
strSql.Format(strTmp, strGlideID.c_str());
strExe = strSql;
if (iLinTag == 1)
{
dbCheck.ExecuteJustSql(strExe);
writeLog(strExe);
}
}

dbProcess.MoveRecordNext();

Sleep(20);
}

if (dbCheck.IsSetOpened())
dbCheck.CloseRecordSet();
if (dbProcess.IsSetOpened())
dbProcess.CloseRecordSet();
dbCheck.CloseDatabase();
dbProcess.CloseDatabase();

Sleep(20000);
}
gThreadIsExit2 = 1;

if (gThreadIsExit1)
{
btn->EnableWindow(TRUE);
}
AfxOleTerm();

return 1;
}


这是整个线程函数,谢谢各位!
orochi_gao 2009-06-02
  • 打赏
  • 举报
回复
1,你调用的方式
2,你的代码
--小F-- 2009-06-02
  • 打赏
  • 举报
回复
代码拿出来看看
pt1314917 2009-06-02
  • 打赏
  • 举报
回复
贴代码吧。
ks_reny 2009-06-02
  • 打赏
  • 举报
回复
貼出代碼吧,應是代碼的問題.
ai_li7758521 2009-06-02
  • 打赏
  • 举报
回复
代码贴出来。这样谁能看你到问题?!
wzy_love_sly 2009-06-02
  • 打赏
  • 举报
回复
插入代码写了2遍?有触发器?
csdyyr 2009-06-02
  • 打赏
  • 举报
回复
代码?
  • 打赏
  • 举报
回复
谢谢各位,尤其是szx1999。可能是这位朋友所说的问题。结帐给分。

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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