- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
bool failed = true;
int count = 0;
do
{
{
ADO cnn( service().connectionString() );
if (count == 0)
{
_RecordsetPtr rs = cnn.Command(L"SELECT MAX(MessNo) as MAXNO FROM RobotLog", ADODB::adCmdText)
.Execute();
if (rs->EndOfFile == VARIANT_FALSE)
{
vt = rs->Fields->Item[L"MAXNO"]->Value;
if (vt.vt != VT_NULL)
messNo = vt.lVal + 1;
}
rs->Close();
}
else
messNo++;
try
{
cnn.Command(L"INSERT INTO RobotLog(MessNo,MessType,MessDate,MessText,Empl_Code,CompName,Robot_Code, "
L"Robot_Name,Doc_Name,Doc_No,Doc_CardDate) VALUES(?,?,?,?,?,?,?,?,?,?,?)", ADODB::adCmdText)
.CreateParameter(messNo)
.CreateParameter((long) messType)
.CreateParameter((DATE) COleDateTime::GetCurrentTime())
.CreateParameter(bstr_t(messText.AllocSysString()))
.CreateParameter((long)m_EmplCode)
.CreateParameter(service().computerName())
.CreateParameter((long)m_ID)
.CreateParameter(sRobotName)
.CreateParameter(sDocName, false)
.CreateParameter(sDoc_No, false)
.CreateParameter(dCardDate)
.Execute();
failed = false;
}
catch(_com_error& )
{
// DebugMsgE("CRobotThread::LogRobotWork[%s] error: 0x%08x::%s - %s. Attempt #:%d", (const char*)m_RobotName, err.Error(), (const char*) err.Description(),
// (const char*) err.ErrorMessage(), count);
}
}
count++;
Sleep(100);
}while (failed && count < 10000);
Вычисляемое значение 'messNo' прописывается в PK. Код выполняется мультипоточночно, примерно из 5 - 15 одновременно работающих потоков.
Вот такая вот попытка 10000 раз прописать неуникальное значение первичного ключа :)
Но, самое смешное, что на моё предложение перенести заботу об уникальности и инкрементации в SQL, мне было велено "не умничать, ЭТО правильный алгоритм !...".