DAORecordSet Fails to update...
-
Can anyone with any more DB experience than me, please suggest ANY reason this doesn't work... its driving me mad! So, the in my UI the user can create an "assembly" by adding "components" to a list. I have an assembly table that links the ID of the assembly with the IDs of its constituent components, and the quantity of each component in the assembly. Users now want to be able to create a new assembly based on an old one, so I need a copy function. Easy I though, I'll just crib the code from the single-component-add function and loop around it... HA! I end up with the new assembly item, but I lose the component list. The code below just creates the requisite number of blank (0, 0, 0) records in the Assembly table, but it all looks right in the debugger. Why?
if (m_pMainGrid->m_bCopyingAssembly)
{
CDaoDatabase* pDB = GetDatabase();
CString Filter;
CAssemRecords* OldAssRS = new CAssemRecords(pDB);
CAssemRecords* NewAssRS = new CAssemRecords(pDB);try
{
Filter.Format("SELECT * FROM Assemblies WHERE [Assembly Key] = %ld", lOldComponentKey);
OldAssRS->Open(dbOpenDynaset, Filter, 0);
NewAssRS->Open(dbOpenDynaset, "SELECT * FROM Assemblies", 0);if (!(OldAssRS->IsBOF() || OldAssRS->IsEOF())) { OldAssRS->MoveFirst(); do { NewAssRS->AddNew(); NewAssRS->Initialise(); NewAssRS->m\_Assembly\_Key = lNewComponentKey; NewAssRS->m\_Item\_Key = OldAssRS->m\_Item\_Key; NewAssRS->m\_Number\_Length = OldAssRS->m\_Number\_Length; NewAssRS->Update(); OldAssRS->MoveNext(); } while (!OldAssRS->IsEOF()); } ASSERT(OldAssRS->IsOpen());//debug if (OldAssRS->IsOpen()) { OldAssRS->Close(); } if (OldAssRS) { delete OldAssRS; } OldAssRS = NULL; ASSERT(NewAssRS->IsOpen());//debug if (NewAssRS->IsOpen()) { NewAssRS->Close(); } if (NewAssRS) { delete NewAssRS; } NewAssRS = NULL; m\_pMainGrid->SetCopyingAssem(FALSE);
}
catch(CDaoException *e)
{
ASSERT(e->ReportError());
e->Delete();
OldAssRS->Close();
NewAssRS->Close();
return;
}
catch(CMemoryException *e)
{
e->Delete();
OldAssRS->Close();
NewAssRS->Close();
return;
}
} -
Can anyone with any more DB experience than me, please suggest ANY reason this doesn't work... its driving me mad! So, the in my UI the user can create an "assembly" by adding "components" to a list. I have an assembly table that links the ID of the assembly with the IDs of its constituent components, and the quantity of each component in the assembly. Users now want to be able to create a new assembly based on an old one, so I need a copy function. Easy I though, I'll just crib the code from the single-component-add function and loop around it... HA! I end up with the new assembly item, but I lose the component list. The code below just creates the requisite number of blank (0, 0, 0) records in the Assembly table, but it all looks right in the debugger. Why?
if (m_pMainGrid->m_bCopyingAssembly)
{
CDaoDatabase* pDB = GetDatabase();
CString Filter;
CAssemRecords* OldAssRS = new CAssemRecords(pDB);
CAssemRecords* NewAssRS = new CAssemRecords(pDB);try
{
Filter.Format("SELECT * FROM Assemblies WHERE [Assembly Key] = %ld", lOldComponentKey);
OldAssRS->Open(dbOpenDynaset, Filter, 0);
NewAssRS->Open(dbOpenDynaset, "SELECT * FROM Assemblies", 0);if (!(OldAssRS->IsBOF() || OldAssRS->IsEOF())) { OldAssRS->MoveFirst(); do { NewAssRS->AddNew(); NewAssRS->Initialise(); NewAssRS->m\_Assembly\_Key = lNewComponentKey; NewAssRS->m\_Item\_Key = OldAssRS->m\_Item\_Key; NewAssRS->m\_Number\_Length = OldAssRS->m\_Number\_Length; NewAssRS->Update(); OldAssRS->MoveNext(); } while (!OldAssRS->IsEOF()); } ASSERT(OldAssRS->IsOpen());//debug if (OldAssRS->IsOpen()) { OldAssRS->Close(); } if (OldAssRS) { delete OldAssRS; } OldAssRS = NULL; ASSERT(NewAssRS->IsOpen());//debug if (NewAssRS->IsOpen()) { NewAssRS->Close(); } if (NewAssRS) { delete NewAssRS; } NewAssRS = NULL; m\_pMainGrid->SetCopyingAssem(FALSE);
}
catch(CDaoException *e)
{
ASSERT(e->ReportError());
e->Delete();
OldAssRS->Close();
NewAssRS->Close();
return;
}
catch(CMemoryException *e)
{
e->Delete();
OldAssRS->Close();
NewAssRS->Close();
return;
}
}Not being familiar with CDO and recordset operations I will give you the pseudo code that I would use copy the assembly record into variables/object insert the variables/object into a new record save the record and get the new assembyid get a list of the old assembly components loop through component list copy component details into variables/object save the component with the new assemblyid repeat for each assembly
Never underestimate the power of human stupidity RAH
-
Can anyone with any more DB experience than me, please suggest ANY reason this doesn't work... its driving me mad! So, the in my UI the user can create an "assembly" by adding "components" to a list. I have an assembly table that links the ID of the assembly with the IDs of its constituent components, and the quantity of each component in the assembly. Users now want to be able to create a new assembly based on an old one, so I need a copy function. Easy I though, I'll just crib the code from the single-component-add function and loop around it... HA! I end up with the new assembly item, but I lose the component list. The code below just creates the requisite number of blank (0, 0, 0) records in the Assembly table, but it all looks right in the debugger. Why?
if (m_pMainGrid->m_bCopyingAssembly)
{
CDaoDatabase* pDB = GetDatabase();
CString Filter;
CAssemRecords* OldAssRS = new CAssemRecords(pDB);
CAssemRecords* NewAssRS = new CAssemRecords(pDB);try
{
Filter.Format("SELECT * FROM Assemblies WHERE [Assembly Key] = %ld", lOldComponentKey);
OldAssRS->Open(dbOpenDynaset, Filter, 0);
NewAssRS->Open(dbOpenDynaset, "SELECT * FROM Assemblies", 0);if (!(OldAssRS->IsBOF() || OldAssRS->IsEOF())) { OldAssRS->MoveFirst(); do { NewAssRS->AddNew(); NewAssRS->Initialise(); NewAssRS->m\_Assembly\_Key = lNewComponentKey; NewAssRS->m\_Item\_Key = OldAssRS->m\_Item\_Key; NewAssRS->m\_Number\_Length = OldAssRS->m\_Number\_Length; NewAssRS->Update(); OldAssRS->MoveNext(); } while (!OldAssRS->IsEOF()); } ASSERT(OldAssRS->IsOpen());//debug if (OldAssRS->IsOpen()) { OldAssRS->Close(); } if (OldAssRS) { delete OldAssRS; } OldAssRS = NULL; ASSERT(NewAssRS->IsOpen());//debug if (NewAssRS->IsOpen()) { NewAssRS->Close(); } if (NewAssRS) { delete NewAssRS; } NewAssRS = NULL; m\_pMainGrid->SetCopyingAssem(FALSE);
}
catch(CDaoException *e)
{
ASSERT(e->ReportError());
e->Delete();
OldAssRS->Close();
NewAssRS->Close();
return;
}
catch(CMemoryException *e)
{
e->Delete();
OldAssRS->Close();
NewAssRS->Close();
return;
}
}:~ As it turns out, in my RecordSet class m_bCheckCacheForDirtyFields was set to FALSE. This turns off automatic double buffering and means you have to manually set fields dirty, otherwise they won't save when you call Update. Blah. Flip the switch and it works...