//*-- AUTHOR : Ilse Koenig //*-- Modified : 03/05/2002 by I. Koenig //*-- Created : 28/09/2000 by I. Koenig //_HADES_CLASS_DESCRIPTION ////////////////////////////////////////////////////////////////////////////// // HStartParOraIo // // Interface class to database Oracle for input/output of parameters needed // by the START detector // (uses the Oracle C/C++ precompiler) // ////////////////////////////////////////////////////////////////////////////// using namespace std; #include "hstartparoraio.h" #include "hades.h" #include "hspectrometer.h" #include "hstartdetector.h" #include "hstartcalpar.h" #include "hstartselfcopar.h" #include "hstartlookup.h" #include "hstartgeompar.h" #include "hgeomcompositevolume.h" #include "hgeomoradetversion.h" #include #include #include #define SQLCA_STORAGE_CLASS extern #define ORACA_STORAGE_CLASS extern // Oracle communication area #include // SQL Communications Area #include ClassImp(HStartParOraIo) #define START_MAXMODS 10 #define START_MAXSTRIPS 300 HStartParOraIo::HStartParOraIo(HOraConn* pC) : HDetParOraIo(pC) { // constructor // sets the name of the I/O class "HStartParIo" // gets the pointer to the connection class fName="HStartParIo"; numModules=0; startIds=0; initModules=0; geomVers=0; } HStartParOraIo::~HStartParOraIo() { // destructor if (initModules) delete initModules; if (startIds) delete startIds; if (geomVers) delete geomVers; } Bool_t HStartParOraIo::init(HParSet* pPar,Int_t* set) { // calls special read-function for each parameter container const Text_t* name=pPar->IsA()->GetName(); if (startIo(pPar)<=0) return kFALSE; if (strcmp(name,"HStartCalPar")==0) return read(((HStartCalPar*)pPar),set); if (strcmp(name,"HStartSelfCoPar")==0) return read(((HStartSelfCoPar*)pPar),set); if (strcmp(name,"HStartLookup")==0) return read(((HStartLookup*)pPar),set); if (strcmp(name,"HStartGeomPar")==0) return read(((HStartGeomPar*)pPar),set); // cout<<"initialization of "<GetName()<<" not possible from Oracle!"<IsA()->GetName(); if (startIo(pPar)<=0) return 0; if (strcmp(name,"HStartCalPar")==0) return writePar((HStartCalPar*)pPar); if (strcmp(name,"HStartSelfCoPar")==0)return writePar((HStartSelfCoPar*)pPar); if (strcmp(name,"HStartLookup")==0) return writePar((HStartLookup*)pPar); cout<<"No write-interface to Oracle for parameter container " <GetName()<0 && startIds==0) readIds(); if (runStart==-1 || numModules<=0) { pPar->setInputVersion(-1,inputNumber); return -1; } return runStart; } Int_t HStartParOraIo::readIds() { // Gets the run start of the actual run // Reads the number of strips of all modules defined for the first run // and stores them in array startIds (the position in the array is // identical with the module position in the setup (0: START 1: VETO) // Returns -1, if the run is not found, or 0, if no modules are found for this run HStartDetector* det=(HStartDetector*)(gHades->getSetup()->getDetector("Start")); //maxModules=det->getMaxModules(); maxModules=det->getMaxModInSetup(); maxStrips=det->getMaxComponents(); if (maxModules>START_MAXMODS || START_MAXSTRIPS < (maxModules*maxStrips)) { Error("HStartParOraIo::readIds()", "Maximum i/o buffer sizes to small:\n maximum number of modules: %i\n" "maximum number of strips: %i", START_MAXMODS,START_MAXSTRIPS); return -1; } EXEC SQL BEGIN DECLARE SECTION; struct { int pos[START_MAXMODS]; int nstrips[START_MAXMODS]; } mods; EXEC SQL END DECLARE SECTION; EXEC SQL WHENEVER SQLERROR DO showSqlError("readIds()"); EXEC SQL WHENEVER NOT FOUND CONTINUE; EXEC SQL SELECT module_pos, n_strips INTO :mods FROM start_ana.det_setup_at_run_hist; numModules=sqlca.sqlerrd[2]; // number of rows returned by select if (numModules>0) { startIds=new TArrayI(START_MAXMODS); for(Int_t i=0;iAddAt(0,i); initModules=new TArrayI(START_MAXMODS); } else { Error("readIds","Error now row returned"); } for(Int_t i=0;igetModule(-1,mods.pos[i])) { startIds->AddAt(mods.nstrips[i],mods.pos[i]); if (mods.nstrips[i]>maxStrips) Error("HStartParOraIo::readIds()", "number of strips in HStartDetector: %i\n" "number of strips in Oracle at position %i: %i", maxStrips,mods.pos[i],mods.nstrips[i]); } } //printNStrips(); return numModules; } void HStartParOraIo::printNStrips() { // prints the number of strips of all modules in the current setup, // which are found in the database if (startIds) { cout<<"START detector modules: "; for(Int_t i=0;iAt(i); cout<<'\n'; } } Bool_t HStartParOraIo::read(HStartLookup* pPar, Int_t* set) { // reads and fills the container "StartLookup" for mapping TDC channels // to strips Int_t contVers=pPar->getInputVersion(inputNumber); Int_t versions[START_MAXMODS]; Int_t version=getVersion(pPar,set,versions); if (version==-1) { pPar->setInputVersion(-1,inputNumber); return kFALSE; } if (contVers==version) return kTRUE; if (inputNumber==1) pPar->clear(); pPar->setInputVersion(version,inputNumber); initModules->Reset(); EXEC SQL BEGIN DECLARE SECTION; int modPos; int vers; struct { int cr[START_MAXSTRIPS]; int sl[START_MAXSTRIPS]; int ch[START_MAXSTRIPS]; int mo[START_MAXSTRIPS]; int st[START_MAXSTRIPS]; char tp[START_MAXSTRIPS][2]; } lookup; struct { short cr[START_MAXSTRIPS]; short sl[START_MAXSTRIPS]; short ch[START_MAXSTRIPS]; short mo[START_MAXSTRIPS]; short st[START_MAXSTRIPS]; short tp[START_MAXSTRIPS]; } lookup_ind; EXEC SQL END DECLARE SECTION; EXEC SQL WHENEVER SQLERROR DO showSqlError("read(HStartLookup*,Int_t*)"); EXEC SQL WHENEVER NOT FOUND CONTINUE; EXEC SQL DECLARE lookup_cur CURSOR FOR SELECT crate, slot, channel, module, strip, type_info FROM start_ana.start_lookuptable_data WHERE module = :modPos AND vers_id = :vers; for(Int_t m=0;mAt(m)>0 && versions[m]>0) { modPos=m+1; vers=versions[m]; EXEC SQL OPEN lookup_cur; EXEC SQL FETCH lookup_cur INTO :lookup INDICATOR :lookup_ind; for(Int_t i=0;isetAddress(lookup.cr[i],lookup.sl[i],lookup.ch[i], m,lookup.st[i],(lookup_ind.tp[i]==-1)?'\0':lookup.tp[i][0]); initModules->AddAt(m+1,m); } } } EXEC SQL CLOSE lookup_cur; Bool_t allFound=kTRUE; for(Int_t i=0;i0 && initModules->At(i)<=0) { allFound=kFALSE; Error("read(HStartLookup*,...)","\n Start Lookup params for module %d not found",i); } } if (allFound) { // pPar->printParam(); setChanged(pPar); printInfo(pPar->GetName()); } return allFound; }; Int_t HStartParOraIo::getVersion(HParSet* pPar,Int_t* set,Int_t* versions) { // reads the version for the calibration and selfcoincidence parameters // valid for the current event file // returns -1, if no data are found HParOraSet* oraSet=getOraSet(pPar); if (oraSet->contextId==-1) return -1; Int_t contVers=pPar->getInputVersion(inputNumber); if (contVers!=-1 && runStart>=oraSet->versDate[0] && runStart<=oraSet->versDate[1]) return contVers; oraSet->clearVersDate(); EXEC SQL BEGIN DECLARE SECTION; int context; struct { int pos[START_MAXMODS]; int vers[START_MAXMODS]; double since[START_MAXMODS]; double until[START_MAXMODS]; } parvers; EXEC SQL END DECLARE SECTION; context=oraSet->contextId; EXEC SQL WHENEVER SQLERROR DO showSqlError("getVersion(HParOraSet*,Int_t)"); EXEC SQL WHENEVER NOT FOUND CONTINUE; const Char_t* containerClass=pPar->IsA()->GetName(); if (strcmp(containerClass,"HStartCalPar")==0) { EXEC SQL SELECT module_pos, version, hdate.to_ansitime(valid_since), hdate.to_ansitime(valid_until) INTO :parvers FROM start_ana.start_calpar_vers_at_date WHERE context_id = :context; } else if (strcmp(containerClass,"HStartSelfCoPar")==0) { EXEC SQL SELECT module_pos, version, hdate.to_ansitime(valid_since), hdate.to_ansitime(valid_until) INTO :parvers FROM start_ana.start_selfcopar_vers_at_date WHERE context_id = :context; } else if (strcmp(containerClass,"HStartLookup")==0) { EXEC SQL SELECT module_pos, version, hdate.to_ansitime(valid_since), hdate.to_ansitime(valid_until) INTO :parvers FROM start_ana.start_lookuptable_vers_at_date WHERE context_id = :context; } for(Int_t i=0;iAt(m)>0) { versions[m]=parvers.vers[i]; if (parvers.since[i]>oraSet->versDate[0]) oraSet->versDate[0]=parvers.since[i]; if (parvers.until[i]versDate[1]) oraSet->versDate[1]=parvers.until[i]; } } if (oraSet->versDate[0]>=0) return getActRunId(); return -1; }; Bool_t HStartParOraIo::read(HStartCalPar* pPar, Int_t* set) { // reads the calibration parameters and fill the StartCalPar container Int_t contVers=pPar->getInputVersion(inputNumber); Int_t versions[START_MAXMODS]; Int_t version=getVersion(pPar,set,versions); Float_t pVal[7]={-1,-1,-1,-1,-1,-1,-1}; if (version==-1) { pPar->setInputVersion(-1,inputNumber); return kFALSE; } if (contVers==version) return kTRUE; if (inputNumber==1) pPar->clear(); pPar->setInputVersion(version,inputNumber); initModules->Reset(); EXEC SQL BEGIN DECLARE SECTION; int modPos; int vers; struct { int strip[START_MAXSTRIPS]; float slo[START_MAXSTRIPS]; float ofs[START_MAXSTRIPS]; float sloR[START_MAXSTRIPS]; float sloL[START_MAXSTRIPS]; float sloM[START_MAXSTRIPS]; float vGr[START_MAXSTRIPS]; float pOfs[START_MAXSTRIPS]; } cal; struct { short strip[START_MAXSTRIPS]; short slo[START_MAXSTRIPS]; short ofs[START_MAXSTRIPS]; short sloR[START_MAXSTRIPS]; short sloL[START_MAXSTRIPS]; short sloM[START_MAXSTRIPS]; short vGr[START_MAXSTRIPS]; short pOfs[START_MAXSTRIPS]; } cal_Ind; EXEC SQL END DECLARE SECTION; EXEC SQL WHENEVER SQLERROR DO showSqlError("read(HStartCalPar*,Int_t*)"); EXEC SQL WHENEVER NOT FOUND CONTINUE; EXEC SQL DECLARE cal_cur CURSOR FOR SELECT strip, slope, offset, slope_r,slope_l,slope_m,v_group,p_offset FROM start_ana.start_calpar_data WHERE module_pos = :modPos AND version = :vers; for(Int_t m=0;mAt(m)>0 && versions[m]>0) { modPos=m; vers=versions[m]; EXEC SQL OPEN cal_cur; EXEC SQL FETCH cal_cur INTO :cal INDICATOR :cal_Ind; for(Int_t i=0;iAddAt(m+1,m); } } } EXEC SQL CLOSE cal_cur; Bool_t allFound=kTRUE; for ( Int_t i=0;i0) { if (initModules->At(i)>0) set[i]=0; else allFound=kFALSE; } } setChanged(pPar); printInfo(pPar->GetName()); return allFound; }; Bool_t HStartParOraIo::read(HStartSelfCoPar* pPar, Int_t* set) { // reads the selfcoincidence parameters and fill the StartSelfCoPar container Int_t contVers=pPar->getInputVersion(inputNumber); Int_t versions[START_MAXMODS]; Int_t s[2]={0,0}; s[0]=set[0]; // only Start module Int_t version=getVersion(pPar,s,versions); if (version==-1) { pPar->setInputVersion(-1,inputNumber); return kFALSE; } if (contVers==version) return kTRUE; pPar->clear(); pPar->setInputVersion(version,inputNumber); EXEC SQL BEGIN DECLARE SECTION; int vers; struct { int strip[START_MAXSTRIPS]; float ti[START_MAXSTRIPS]; float hw[START_MAXSTRIPS]; } sco; struct { short strip[START_MAXSTRIPS]; short ti[START_MAXSTRIPS]; short hw[START_MAXSTRIPS]; } sco_Ind; EXEC SQL END DECLARE SECTION; EXEC SQL WHENEVER SQLERROR GOTO error_found; if (set[0] && startIds->At(0)>0 && versions[0]>0) { vers=versions[0]; // cout<<"SelfCoPar: Version: "<0) { setChanged(pPar); cout<GetName()<<" initialized from Oracle\n"; return kTRUE; } } return kFALSE; error_found: showSqlError("read(HStartCalPar*,Int_t*)"); return kFALSE; } Bool_t HStartParOraIo::read(HStartGeomPar* pPar, Int_t* set) { // reads the geometry of the START and fills the StartGeomPar container Bool_t allFound=kTRUE; Int_t detId=-1; if (!geomVers) { detId=getDetectorId(pPar->getDetectorName()); geomVers=new HGeomOraDetVersion(pPar->getDetectorName(),detId); } else { detId=geomVers->getDetectorId(); } if (detId<=0) { allFound=kFALSE; delete geomVers; geomVers=0; } if (detId>0&&pPar->isFirstInitialization()) { if (!readModGeomNames(pPar,set) || !readCompGeomNames(pPar,set)) { allFound=kFALSE; pPar->clear(); } else addGeomOraSet(pPar); } if (allFound) allFound=readDetectorGeometry(pPar,set,geomVers); return allFound; } Bool_t HStartParOraIo::readModGeomNames(HStartGeomPar* pPar,Int_t* set) { // reads the geometry object names of all modules EXEC SQL BEGIN DECLARE SECTION; struct { int pos[START_MAXMODS]; varchar oname[START_MAXMODS][9]; } mods; EXEC SQL END DECLARE SECTION; EXEC SQL WHENEVER SQLERROR DO showSqlError("readModGeomNames"); EXEC SQL WHENEVER NOT FOUND CONTINUE; EXEC SQL SELECT module_pos, geom_obj_name INTO :mods FROM start_ana.det_setup_at_run_hist; Int_t nMods=sqlca.sqlerrd[2]; // number of rows returned by select Bool_t allFound=kTRUE; if (nMods>0) { initModules->Reset(); Int_t m; for(Int_t i=0;igetModule(-1,m); if (set[m] && pMod && startIds->At(m)>0) { mods.oname[i].arr[mods.oname[i].len]='\0'; pMod->SetName((Char_t*)(mods.oname[i].arr)); initModules->AddAt(m+1,m); pMod->setRefName(pMod->GetName()); Int_t mr=pPar->getModNumInMod(pMod->GetName()); HGeomCompositeVolume* refMod=pPar->getRefVolume(mr); if (refMod==0) { refMod=new HGeomCompositeVolume(pPar->getNumComponents()); refMod->SetName(pMod->GetName()); pPar->addRefVolume(refMod,mr); } pMod->setVolume(refMod); } } for(Int_t i=0;i0 && initModules->At(i)==0) allFound=kFALSE; } } else allFound=kFALSE; return allFound; } Bool_t HStartParOraIo::readCompGeomNames(HStartGeomPar* pPar,Int_t* set) { // reads the geometry object names of all modules and the geometry version EXEC SQL BEGIN DECLARE SECTION; struct { int pos[START_MAXSTRIPS]; int strip[START_MAXSTRIPS]; varchar oname[START_MAXSTRIPS][9]; } strips; EXEC SQL END DECLARE SECTION; EXEC SQL WHENEVER SQLERROR DO showSqlError("readCompGeomNames"); EXEC SQL WHENEVER NOT FOUND CONTINUE; EXEC SQL SELECT module_pos, strip_no, geom_obj_name INTO :strips FROM start_ana.det_strip; Int_t nStrips=sqlca.sqlerrd[2]; // number of rows returned by select Int_t m; for(Int_t i=0;igetModule(-1,m); if (set[m] && pMod) { HGeomCompositeVolume* pRefMod=pMod->getRefVolume(); HGeomVolume* volu=pRefMod->getComponent(strips.strip[i]); strips.oname[i].arr[strips.oname[i].len]='\0'; volu->SetName((Char_t*)(strips.oname[i].arr)); initModules->AddAt(m+1,m); } } Bool_t allFound=kTRUE; for(Int_t i=0;i0 && initModules->At(i)==0) allFound=kFALSE; } return allFound; }; Int_t HStartParOraIo::writePar(HStartCalPar* pPar) { // creates a new version and writes the calibration parameters to Oracle Int_t version=createVers(pPar); if (version==-1) return -1; EXEC SQL BEGIN DECLARE SECTION; int pos[START_MAXSTRIPS]; int strip[START_MAXSTRIPS]; int vers[START_MAXSTRIPS]; float slo[START_MAXSTRIPS]; float ofs[START_MAXSTRIPS]; float sloR[START_MAXSTRIPS]; float sloL[START_MAXSTRIPS]; float sloM[START_MAXSTRIPS]; float vGr[START_MAXSTRIPS]; float pOfs[START_MAXSTRIPS]; int rows_to_insert; EXEC SQL END DECLARE SECTION; for(Int_t m=0; mgetSize(); m++) { HStartCalParMod& rMod= (*pPar)[m]; Int_t nChan=0; Int_t nModSize=0; //////////////////////////////////////// // For 2 types of Start Det. // Diamond: 8 Strips, modules: 0,1,2 (HI exp.) // Fiber: 32 channels, modules: 3,4,5 (Sep03,Jan04) //////////////////////////////////////// if (startIds->At(m)>0) { switch (m) { case 0: case 1: case 2: nModSize=8; break; default: nModSize=rMod.getSize(); break; } //printf("Module %d size %d \n",m,nModSize); for(Int_t c=0; cAt(m)) { Error("writePar(HStartCalPar*)", "\n Number of strips in Oracle: %i" " \n Number of channels in StartCalPar: %i\n", startIds->At(m),nChan); rollback(); return -1; } EXEC SQL WHENEVER SQLERROR GOTO not_found; EXEC SQL WHENEVER NOT FOUND GOTO not_found; EXEC SQL FOR :rows_to_insert INSERT INTO start_ana.calpar_data (strip_id, vers_id, slope, offset,slope_r,slope_l,slope_m,v_group,p_offset) VALUES (start_ana.start_par_query.get_strip_id(:pos,:strip), :vers, :slo, :ofs, :sloR,:sloL,:sloM,:vGr,:pOfs); //cout<<"module_pos: "<setChanged(kFALSE); return version; not_found: showSqlError("writePar(HStartCalPar*)"); rollback(); pPar->setChanged(kFALSE); return -1; } Int_t HStartParOraIo::writePar(HStartSelfCoPar* pPar) { // creates a new version and writes the calibration parameters to Oracle Int_t version=createVers(pPar); if (version==-1) return -1; EXEC SQL BEGIN DECLARE SECTION; int pos[START_MAXSTRIPS]; int strip[START_MAXSTRIPS]; int vers[START_MAXSTRIPS]; float ti[START_MAXSTRIPS]; float hw[START_MAXSTRIPS]; int rows_to_insert; EXEC SQL END DECLARE SECTION; HStartSelfCoParMod& rMod= (*pPar)[0]; Int_t nChan=0; if (startIds->At(0)>0) { for(Int_t c=0; csetChanged(kFALSE); return -1; } rows_to_insert=nChan; if (nChan != startIds->At(0)) { Error("writePar(HStartSelfCoPar*)", "\n Number of strips in Oracle: %i" " \n Number of channels in StartSelfCoPar: %i\n", startIds->At(0),nChan); rollback(); return -1; } EXEC SQL WHENEVER SQLERROR GOTO not_found; EXEC SQL WHENEVER NOT FOUND GOTO not_found; EXEC SQL FOR :rows_to_insert INSERT INTO start_ana.selfcopar_data (strip_id, vers_id, time, halfwidth) VALUES (start_ana.start_par_query.get_strip_id(:pos,:strip), :vers, :ti, :hw); cout<<"Start module: "<setChanged(kFALSE); return version; not_found: showSqlError("writePar(HStartSelfCoPar*)"); rollback(); pPar->setChanged(kFALSE); return -1; } Int_t HStartParOraIo::writePar(HStartLookup* pPar) { // creates a new version and writes the calibration parameters to Oracle Int_t version=createVers(pPar); if (version==-1) return -1; EXEC SQL BEGIN DECLARE SECTION; int rows_to_insert; int vers[START_MAXSTRIPS]; int cr[START_MAXSTRIPS]; int sl[START_MAXSTRIPS]; int ch[START_MAXSTRIPS]; int mo[START_MAXSTRIPS]; int st[START_MAXSTRIPS]; char tp[START_MAXSTRIPS][2]; EXEC SQL END DECLARE SECTION; Int_t nTdc=pPar->getSize(); Int_t nChan=0, module; Int_t nChanTmp[START_MAXMODS]; for(Int_t n=0;n=0) { vers[nChan]=version; cr[nChan]=tdc.getCrate(); sl[nChan]=tdc.getSlot(); ch[nChan]=j; mo[nChan]=module+1; st[nChan]=chan.getStrip(); tp[nChan][0]=chan.getType(); tp[nChan][1]='\0'; nChan++; nChanTmp[module]++; } } } if (nChan==0) { version=-1; } else { for(Int_t n=0;nAt(n)) { version=-1; Info("writePar(HStartLookup*)", "\n Check your setup or params!!!" "\n Number of strips in Oracle for module %i: %i " "\n Number of channels in StartLookupPar: %i\n", n,startIds->At(n),nChanTmp[n]); } } } if (version==-1) { pPar->setChanged(kFALSE); return -1; } rows_to_insert=nChan; EXEC SQL WHENEVER SQLERROR GOTO not_found; EXEC SQL WHENEVER NOT FOUND GOTO not_found; EXEC SQL FOR :rows_to_insert INSERT INTO start_ana.START_LOOKUPTABLE_DATA (vers_id,crate, slot, channel, module, strip, type_info) VALUES (:vers,:cr,:sl,:ch,:mo,:st,:tp); cout<<"Start Lookup table: "<setChanged(kFALSE); return version; not_found: showSqlError("writePar(HStartLookup*)"); rollback(); pPar->setChanged(kFALSE); return -1; } Int_t HStartParOraIo::createVers(HParSet* pPar) { // creates a new version for the calibration or selfcoincidence parameters // return the new version cout<<"--------------- "<GetName()<<" ---------------\n"; if (strlen(pPar->getAuthor())==0) { Error("createVers(HParSet*)", "author of parameters not defined"); return -1; } if (strlen(pPar->getDescription())==0) { Error("createVers(HParSet*)", "descriction of parameters not defined"); return -1; } EXEC SQL BEGIN DECLARE SECTION; int vers=-1; int context=-1; int run; char* creator; char* descript; EXEC SQL END DECLARE SECTION; context = getContextId(pPar->IsA()->GetName(),pPar->getParamContext()); if (context==-1) return -1; run=getActRunId(); creator=(Char_t*)pPar->getAuthor(); descript=(Char_t*)pPar->getDescription(); EXEC SQL WHENEVER SQLERROR GOTO not_found; EXEC SQL WHENEVER NOT FOUND GOTO not_found; const Char_t* contName=pPar->IsA()->GetName(); if (strcmp(contName,"HStartCalPar")==0) { EXEC SQL EXECUTE BEGIN SELECT start_ana.start_par_query.next_version INTO :vers FROM DUAL; INSERT INTO start_ana.calpar_vers (vers_id, orig_context_id, run_id, author, description) VALUES (:vers, :context, :run, :creator, :descript); END; END-EXEC; } else if (strcmp(contName,"HStartSelfCoPar")==0) { EXEC SQL EXECUTE BEGIN SELECT start_ana.start_par_query.next_version INTO :vers FROM DUAL; INSERT INTO start_ana.selfcopar_vers (vers_id, orig_context_id, run_id, author, description) VALUES (:vers, :context, :run, :creator, :descript); END; END-EXEC; } else if (strcmp(contName,"HStartLookup")==0) { EXEC SQL EXECUTE BEGIN SELECT start_ana.start_par_query.next_version INTO :vers FROM DUAL; INSERT INTO start_ana.START_LOOKUPTABLE_VERS (vers_id, orig_context_id, run_id, author, description) VALUES (:vers, :context, :run, :creator, :descript); END; END-EXEC; } cout<<"Oracle version for "<GetName()<<" created: "<GetName()<<" created: "<At(i)) { if (first) { cout<At(i)-1)<<" "; } } cout<<'\n'; }