C++使用ocilib访问oracle的函数

1、oracle中处理

建类型和函数

--建类型
/*
这些用于结构操作:
一个data_table_type数据列表有多条data_type数据,
一条data_type数据有fileinfo_type文件信息和seriesinfo_table_type分析项列表信息
一个fileinfo_type文件信息有NUM列号,DEVICENAME品名,LOTID,BATCHNUM批次,ENDDATE测试日期,TOTAL总数,PASS通过数,BINIT是否初测等
一个seriesinfo_table_type分析项列表信息有多个seriesinfo_type分析项信息
一个seriesinfo_type分析项信息有SERIESNAME分析项,PASSNUM这个分析项的通过数
*/
create or replace type seriesinfo_type as OBJECT (SERIESNAME VARCHAR2(50),PASSNUM NUMBER(10));
--OBJECT类型:seriesinfo_type,含有两个变量SERIESNAME和PASSNUM
/

create or replace type seriesinfo_table_type as table of  seriesinfo_type;
--table类型:seriesinfo_table_type,是seriesinfo_type的集合
/

create or replace type fileinfo_type as OBJECT(
NUM  NUMBER(10), DEVICENAME VARCHAR2(100),
LOTID  VARCHAR2(100), BATCHNUM VARCHAR2(100),
ENDDATE VARCHAR2(20), TOTAL  NUMBER(10),
PASS NUMBER(10), BINIT VARCHAR2(10));
--OBJECT类型:fileinfo_type,含有NUM,DEVICENAME,。。。,BINIT
/

create or replace type data_type as OBJECT(filedata fileinfo_type,series_array seriesinfo_table_type);
--OBJECT类型:data_type,含有fileinfo_type和seriesinfo_table_type
/

create or replace type data_table_type as table of data_type;
--table类型:data_type,是data_type的集合
/

--建函数
create or replace function select_data return data_table_type as
--选择数据,返回值是一个结构体的集合,每个结构体含有fileinfo的一条记录和这个num对应的seriesinfo表的多条记录
--定义的自定义类型
v_seriesinfo seriesinfo_type;
v_seriesinfo_table seriesinfo_table_type;
v_fileinfo fileinfo_type;
v_data data_type;
v_data_table data_table_type;--返回值
--定义seriesinfo游标
type seriesinfo_cursor_type is ref cursor;
seriesinfo_cursor seriesinfo_cursor_type;
--定义fileinfo游标
type fileinfo_cursor_type is ref cursor;
fileinfo_cursor fileinfo_cursor_type;
--拼接的seriesinfo sql语句
v_seriesinfo_sql varchar2(200);
begin
  v_data_table := data_table_type();
  v_data := data_type(null,null);
  v_fileinfo := fileinfo_type(null,null,null,null,null,null,null,null);
  --创建遍历fileinfo的游标
  open fileinfo_cursor for
    select NUM,DEVICENAME,LOTID,BATCHNUM,ENDDATE,TOTAL,PASS,BINIT from fileinfo order by devicename,lotid,batchnum,enddate;
  loop fetch fileinfo_cursor into v_fileinfo.NUM,v_fileinfo.DEVICENAME,v_fileinfo.LOTID,
    v_fileinfo.BATCHNUM,v_fileinfo.ENDDATE,v_fileinfo.TOTAL,v_fileinfo.PASS,v_fileinfo.BINIT;
    exit when fileinfo_cursor%notfound;
    --dbms_output.put_line('NUM:'||v_fileinfo.NUM);
    --对于每个num号,创建一条执行seriesinfo的sql语句
    v_seriesinfo_sql:='select SERIESNAME,PASSNUM from seriesinfo_'||v_fileinfo.num;
    v_seriesinfo_table := seriesinfo_table_type(); --seriesinfo_table_type
    v_seriesinfo := seriesinfo_type(null,null);
    --创建遍历这个seriesinfo的游标
    open seriesinfo_cursor for v_seriesinfo_sql;
    loop fetch seriesinfo_cursor into v_seriesinfo.SERIESNAME,v_seriesinfo.PASSNUM;
    exit when seriesinfo_cursor%notfound;
    v_seriesinfo_table.extend;
    v_seriesinfo_table(v_seriesinfo_table.count) := seriesinfo_type(v_seriesinfo.SERIESNAME,v_seriesinfo.PASSNUM);
    --dbms_output.put_line('----SERIESNAME:'||v_seriesinfo.SERIESNAME||',PASSNUM:'||v_seriesinfo.PASSNUM);
    end loop;
    close seriesinfo_cursor;
  v_data_table.extend;
  v_data_table(v_data_table.count) := data_type(v_fileinfo,v_seriesinfo_table);
  --exit;--暂时只需执行一次
  end loop;
  close fileinfo_cursor;
  return v_data_table;
end;
/


2、C++中处理
C++中数据类型

	struct DescInfo //文件的具体描述信息, 是文件信息的一个子集
	{
		CString EndDate;//测试结束日期 年月日 时分秒
		CString MatchineName;//机器名
		CString ProgramName;//程序名
		CString Version;//版本号
		int Total;//总数
		int Pass;//Pass数
		bool bInit;//是否是初测
		std::map  SeriesPassMap;//该文件中的各个项的Pass数
		DescInfo()
		{
			Total = 0;
			Pass = 0;
			bInit = false;
		}
	};
	using measureList = std::vector;//一个批次里面的多次测量列表
	using BatchMap = std::map;//批次Map
	using LotMap = std::map;//Lot的Map
	using DeviceMap = std::map;//品名的Map

调用oracle函数

DeviceMap ReadHistoryInfo(const ocilib::Connection &con)
{
	using namespace ocilib;

	DeviceMap CurrDeviceMap; //品名的Map

	CString predevicename, prelotID, prebatch;//标志符号:上一次读取到的品名、lot号、批次

	try
	{
		DWORD starttime = GetTickCount();
		Statement st(con);
		
		TypeInfo seriesinfo_table_type(con, "seriesinfo_table_type", TypeInfo::Type);
		Collection coll(seriesinfo_table_type);

		DescInfo tmpDescInfo;
		CString tmpBatch, tmpLotID, tmpDeviceName;
		CString tmpBinit;
		long long tmpnum;
		CString tmpseries;
		int tmppassnum;
		Object FD, SA;

		st.Execute("select * from table(select_data)");
		Resultset rs = st.GetResultset();
		while (rs++)
		{
			//获取数据
			FD = rs.Get("filedata");//filedata
			tmpDeviceName = FD.Get("DEVICENAME").c_str();
			tmpLotID = FD.Get("LOTID").c_str();
			tmpBatch = FD.Get("BATCHNUM").c_str();
			tmpDescInfo.EndDate = FD.Get("ENDDATE").c_str();
			tmpDescInfo.Total = FD.Get("TOTAL");
			tmpDescInfo.Pass = FD.Get("PASS");
			tmpBinit = FD.Get("BINIT").c_str();
			tmpDescInfo.bInit = tmpBinit == _T("1") ? true : false;
			tmpnum = FD.Get("NUM");

			coll = rs.Get>("series_array");
			for (unsigned int index = 1, n = coll.GetSize(); index <= n; index++)
			{
				SA = static_cast(coll[index]);
				tmpseries = SA.Get("SERIESNAME").c_str();
				tmppassnum = SA.Get("PASSNUM");
				tmpDescInfo.SeriesPassMap.insert({ tmpseries, tmppassnum });
			}

			//////////////////////////////////////////////////////////////////////////
			//处理数据
			/*
			*算法描述:对于按照devicename,lotid,batchnum,enddate排好序的数据记录来讲
			*如果上一次的品名和这次的品名一样
			*	如果上一次的Lot号和这次的Lot号一样
			*		如果上一次的批次和这次的批次一样
			*			在这次的批次上插入测试列表
			*		否则,添加这个批次(含测试列表)
			*	否则,添加这个Lot号(含批次)
			*否则,添加这个品名(含Lot号)
			*注意结合predevicename、prelotID、prebatch这几个变量来处理,
			*这几个变量的修改也要注意)
			*/
			//构建临时的容器
			measureList tmpmeasureList({ tmpDescInfo });
			BatchMap tmpBatchMap; tmpBatchMap.insert({ tmpBatch, tmpmeasureList });
			LotMap tmpLotMap; tmpLotMap.insert({ tmpLotID, tmpBatchMap });

			//判断上一次是不是这个品名
			if (predevicename == tmpDeviceName)//上一次也是这个品名
			{
				LotMap &CurrLotMap = CurrDeviceMap[tmpDeviceName];
				
				//判断上一次是不是这个Lot号
				if (prelotID == tmpLotID)//上一次也是这个LotID
				{
					BatchMap &CurrBatchMap = CurrLotMap[tmpLotID];

					//判断上一次是不是这个批次
					if (prebatch == tmpBatch)//上一次也是这个批次
					{
						CurrBatchMap[tmpBatch].emplace_back(tmpDescInfo);
					} 
					else//上一次不是这个批次
					{
						CurrBatchMap[tmpBatch] = tmpmeasureList;

						prebatch = tmpBatch;
					}
				} 
				else//上一次不是这个LotID
				{
					CurrLotMap[tmpLotID] = tmpBatchMap;

					prelotID = tmpLotID;
					prebatch = tmpBatch;
				}
			}
			else//上一次不是这个品名
			{
				CurrDeviceMap[tmpDeviceName] = tmpLotMap;

				predevicename = tmpDeviceName;
				prelotID = tmpLotID;
				prebatch = tmpBatch;
			}
		}
	}
	catch (std::exception &ex)   
	{ 
		//std::cout << ex.what() << std::endl; 
		AfxMessageBox(CString(ex.what()));
	}    

	return CurrDeviceMap;
}


你可能感兴趣的:(oracle)