⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lobdlg.cpp

📁 C++OCI,针对8.0.4以上的数据库
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		e->ReportError();
		e->Delete();
		return ;
	}

	CButton *pctrlButt = (CButton *)GetDlgItem(IDC_INFO);
	CListCtrl *pList = (CListCtrl *)GetDlgItem(IDC_LIST2);
	char szInfoArr[512];

	//首先是要获得指向LOB列的指针,这要通过查询语句
	char szSQLArr[512];
	memset(szSQLArr, 0, 512);
	sprintf(szSQLArr, "SELECT image FROM lob_test");

	OCIHANDLE hOCI;
	hOCI.bEnvInit = m_oOCIBase.m_hOCI.bEnvInit;
	hOCI.bErrInit = m_oOCIBase.m_hOCI.bErrInit;
	hOCI.bLdaDefInit = m_oOCIBase.m_hOCI.bLdaDefInit;
	hOCI.bSessionInit = m_oOCIBase.m_hOCI.bSessionInit;
	hOCI.bSrvInit = m_oOCIBase.m_hOCI.bSrvInit;
	hOCI.bStmtInit = m_oOCIBase.m_hOCI.bStmtInit;
	hOCI.bSvcInit = m_oOCIBase.m_hOCI.bSvcInit;
	hOCI.phEnv = m_oOCIBase.m_hOCI.phEnv;
	hOCI.phErr = m_oOCIBase.m_hOCI.phErr;
    hOCI.phServer = m_oOCIBase.m_hOCI.phServer;
	hOCI.phService = m_oOCIBase.m_hOCI.phService;
	hOCI.phSession = m_oOCIBase.m_hOCI.phSession;
	hOCI.phStmt = m_oOCIBase.m_hOCI.phStmt;
	hOCI.pLdaDef = m_oOCIBase.m_hOCI.pLdaDef;

    //准备SQL语句送到Oracle中
	char szInfoStrArr[512];
	int nErrCode = 0;
	int rc = OCIStmtPrepare(hOCI.phStmt,
		                    hOCI.phErr,
						    (text *)szSQLArr,
						    (ub4)strlen((char *)szSQLArr),
						    (ub4)OCI_NTV_SYNTAX,
						    (ub4)OCI_DEFAULT);
	if(OCI_SUCCESS != rc)
	{
		//获取错误信息
		m_oOCIBase.GetOCIErrInfo(hOCI.phErr, nErrCode, szInfoStrArr, 256);
		memset(szInfoArr, 0, 512);
		sprintf(szInfoArr, "无法准备SQL语句.\n ORA-%d: %s", nErrCode, szInfoStrArr);
		pctrlButt->SetWindowText((LPCTSTR)szInfoArr);
		return ;
	}

	//定义指向大对象的指针
	OCILobLocator *pLob;
	static OCIDefine *pDefn = (OCIDefine *) 0;
	rc = OCIDescriptorAlloc((dvoid *)hOCI.phEnv, 
				            (dvoid **)&pLob,
							(ub4)OCI_DTYPE_LOB,
							(size_t)0,
							(dvoid **)0);
	if(OCI_SUCCESS != rc)
	{
		m_oOCIBase.GetOCIErrInfo(hOCI.phErr, nErrCode, szInfoStrArr, 256);
		memset(szInfoArr, 0, 512);
		sprintf(szInfoArr, "无法无法开辟大对象存放的空间.\n ORA-%d: %s", nErrCode, szInfoStrArr);
		pctrlButt->SetWindowText((LPCTSTR)szInfoArr);
		return ;
	}
	
	//绑定指针
	rc = OCIDefineByPos(hOCI.phStmt,
		                &pDefn,
						hOCI.phErr,
						1,
						(dvoid *)&pLob,
						(sb4) -1,
						(ub2)SQLT_BLOB,
						(dvoid *)0,
						(ub2 *)0,
						(ub2 *)0,
						(ub4)OCI_DEFAULT);
	if(OCI_SUCCESS != rc)
	{
		m_oOCIBase.GetOCIErrInfo(hOCI.phErr, nErrCode, szInfoStrArr, 256);
		memset(szInfoArr, 0, 512);
		sprintf(szInfoArr, "无法绑定SQL语句.\n ORA-%d: %s", nErrCode, szInfoStrArr);
		pctrlButt->SetWindowText((LPCTSTR)szInfoArr);
		return ;
	}

	//执行SQL语句,获得指向LOB数据的指针
	rc = OCIStmtExecute(hOCI.phService,
		                hOCI.phStmt,
						hOCI.phErr,
						(ub4)1,
						(ub4)0,
						(CONST OCISnapshot *) 0, 
						(OCISnapshot *) 0,
						(ub4)OCI_DEFAULT);
	if(OCI_SUCCESS != rc && OCI_SUCCESS_WITH_INFO != rc)
	{
		m_oOCIBase.GetOCIErrInfo(hOCI.phErr, nErrCode, szInfoStrArr, 256);
		memset(szInfoArr, 0, 512);
		sprintf(szInfoArr, "无法执行SQL语句.\n ORA-%d: %s", nErrCode, szInfoStrArr);
		pctrlButt->SetWindowText((LPCTSTR)szInfoArr);
		return ;
	}

	//文件名
	char szFileArr[256];

	int nCount = 0;
	DWORD dwStart = 0;
	int nItemCount = 0;
	char szItemArr[30];
	//取出数据
	do
	{
		memset(szFileArr, 0, 256);
		sprintf(szFileArr, "%s%d", szDirArr, GetTickCount()); 
         
		sprintf(szInfoArr, "正在读取第 %d 个记录,数据存放在:\n%s", nCount, szFileArr);
		pctrlButt->SetWindowText((LPCTSTR)szInfoArr);
		
		UpdateData(TRUE);
		nItemCount = pList->GetItemCount();
		sprintf(szItemArr, "%d", nItemCount);
		pList->InsertItem(nItemCount, szItemArr);
		pList->SetItemText(nItemCount, 1, szInfoArr); 
		pList->EnsureVisible(nItemCount, FALSE); 
		
		dwStart = GetTickCount(); 
		ReadLob(szFileArr, hOCI, pLob);
		sprintf(szInfoArr, "正在读取第 %d 个记录,耗时:%d 毫秒", nCount, GetTickCount() - dwStart);
		//pctrlButt->SetWindowText((LPCTSTR)szInfoArr);
		nItemCount = pList->GetItemCount();
		sprintf(szItemArr, "%d", nItemCount);
		pList->InsertItem(nItemCount, szItemArr);
		pList->SetItemText(nItemCount, 1, szInfoArr); 
		pList->EnsureVisible(nItemCount, FALSE);
		UpdateData(FALSE);
		
		nCount ++;

		rc = OCIStmtFetch(hOCI.phStmt, hOCI.phErr, 1, OCI_FETCH_NEXT, OCI_DEFAULT);
		m_oOCIBase.GetOCIErrInfo(hOCI.phErr, nErrCode, szInfoStrArr, 256);
	}while((rc == OCI_SUCCESS) || (rc == OCI_SUCCESS_WITH_INFO));

	//释放内存
	OCIDescriptorFree(pLob, OCI_DTYPE_LOB);	
}

//指定的文件写入指定的LOB列中
//成功,返回1,否则返回0
int CLOBDlg::WriteDataToLOB(CString strFile, OCIHANDLE hOCI, int nPKValue)
{
	//检查参数的有效性
	if(strFile.IsEmpty())
	{
		MessageBox("没有指定数据文件!", "提示", MB_OK|MB_ICONINFORMATION);
		return 0;
	}

	if(!hOCI.bSvcInit || NULL == hOCI.phService)
	{
		MessageBox("OCI的连接句柄没有被初始化!", "提示", MB_OK|MB_ICONINFORMATION);
		return 0;
	}

	CButton *pctrlButt = (CButton *)GetDlgItem(IDC_INFO);
	char szInfoArr[512];
	sprintf(szInfoArr, "正在加载非LOB数据到ID列:ID=%d ", nPKValue);
    
	//向表中插入相关的非LOB数据
	int rc = Insert_NoLobCol(hOCI, nPKValue); 
	if(0 == rc)
	{
		sprintf(szInfoArr, "无法加载非LOB数据到ID列:ID=%d ", nPKValue);
		pctrlButt->SetWindowText((LPCTSTR)szInfoArr);
		return 0;
	}

	//把文件数据加载到LOB列中
	sprintf(szInfoArr, "正在加载文件数据:%s \n 到image列中,条件是:ID=%d ", strFile.GetBuffer(strFile.GetLength()), nPKValue);
	strFile.ReleaseBuffer(); 
    pctrlButt->SetWindowText((LPCTSTR)szInfoArr);
	
	//首先是要获得指向LOB列的指针,这要通过查询语句
	char szSQLArr[512];
	memset(szSQLArr, 0, 512);
	//sprintf(szSQLArr, "SELECT image FROM lob_test WHERE id = %d FOR UPDATE", nPKValue);
	sprintf(szSQLArr, "SELECT image FROM lob_test WHERE id in (select max(id) from lob_test)  FOR UPDATE");

    //准备SQL语句送到Oracle中
	char szInfoStrArr[512];
	int nErrCode = 0;
	rc = OCIStmtPrepare(hOCI.phStmt,
		                hOCI.phErr,
						(text *)szSQLArr,
						(ub4)strlen((char *)szSQLArr),
						(ub4)OCI_NTV_SYNTAX,
						(ub4)OCI_DEFAULT);
	if(OCI_SUCCESS != rc)
	{
		//获取错误信息
		m_oOCIBase.GetOCIErrInfo(hOCI.phErr, nErrCode, szInfoStrArr, 256);
		memset(szInfoArr, 0, 512);
		sprintf(szInfoArr, "无法准备SQL语句.\n ORA-%d: %s", nErrCode, szInfoStrArr);
		pctrlButt->SetWindowText((LPCTSTR)szInfoArr);
		return 0;
	}

	//定义指向大对象的指针
	OCILobLocator *pLob;
	static OCIDefine *pDefn = (OCIDefine *) 0;
	rc = OCIDescriptorAlloc((dvoid *)hOCI.phEnv, 
				            (dvoid **)&pLob,
							(ub4)OCI_DTYPE_LOB,
							(size_t)0,
							(dvoid **)0);
	if(OCI_SUCCESS != rc)
	{
		m_oOCIBase.GetOCIErrInfo(hOCI.phErr, nErrCode, szInfoStrArr, 256);
		memset(szInfoArr, 0, 512);
		sprintf(szInfoArr, "无法无法开辟大对象存放的空间.\n ORA-%d: %s", nErrCode, szInfoStrArr);
		pctrlButt->SetWindowText((LPCTSTR)szInfoArr);
		return 0;
	}
	
	//绑定指针
	rc = OCIDefineByPos(hOCI.phStmt,
		                &pDefn,
						hOCI.phErr,
						1,
						(dvoid *)&pLob,
						(sb4) -1,
						(ub2)SQLT_BLOB,
						(dvoid *)0,
						(ub2 *)0,
						(ub2 *)0,
						(ub4)OCI_DEFAULT);
	if(OCI_SUCCESS != rc)
	{
		m_oOCIBase.GetOCIErrInfo(hOCI.phErr, nErrCode, szInfoStrArr, 256);
		memset(szInfoArr, 0, 512);
		sprintf(szInfoArr, "无法绑定SQL语句.\n ORA-%d: %s", nErrCode, szInfoStrArr);
		pctrlButt->SetWindowText((LPCTSTR)szInfoArr);
		return 0;
	}

	//执行SQL语句,获得指向LOB数据的指针
	rc = OCIStmtExecute(hOCI.phService,
		                hOCI.phStmt,
						hOCI.phErr,
						(ub4)1,
						(ub4)0,
						(CONST OCISnapshot *) 0, 
						(OCISnapshot *) 0,
						(ub4)OCI_DEFAULT);
	if(OCI_SUCCESS != rc && OCI_SUCCESS_WITH_INFO != rc)
	{
		m_oOCIBase.GetOCIErrInfo(hOCI.phErr, nErrCode, szInfoStrArr, 256);
		memset(szInfoArr, 0, 512);
		sprintf(szInfoArr, "无法执行SQL语句.\n ORA-%d: %s", nErrCode, szInfoStrArr);
		pctrlButt->SetWindowText((LPCTSTR)szInfoArr);
		return 0;
	}

	//把数据写入LOB中
	rc = WriteLob((char *)strFile.GetBuffer(strFile.GetLength()), hOCI, pLob);
	if(0 == rc)
	{
		strFile.ReleaseBuffer(); 
		sprintf(szInfoArr, "无法加载文件数据:%s \n 到image列中,条件是:ID=%d ", strFile.GetBuffer(strFile.GetLength()), nPKValue);
		strFile.ReleaseBuffer(); 
		pctrlButt->SetWindowText((LPCTSTR)szInfoArr);
		return 0;
	}

	rc = OCITransCommit(hOCI.phService, hOCI.phErr, OCI_DEFAULT);
	if(OCI_SUCCESS != rc && OCI_SUCCESS_WITH_INFO != rc)
	{
		strFile.ReleaseBuffer(); 
		sprintf(szInfoArr, "无法对加载文件数据:%s \n 到image列中,条件是:ID=%d 提交事务!", strFile.GetBuffer(strFile.GetLength()), nPKValue);
		strFile.ReleaseBuffer(); 
		pctrlButt->SetWindowText((LPCTSTR)szInfoArr);
		return 0;
	}
	
	strFile.ReleaseBuffer(); 
	//释放内存
	OCIDescriptorFree(pLob, OCI_DTYPE_LOB);

	//成功,返回
	return 1; 
}

//在非Lob列中插入数据
//成功,返回1,否则返回0
int CLOBDlg::Insert_NoLobCol(OCIHANDLE hOCI, int nPKValue)
{
	char szInfoStrArr[256];
	char szErrInfoArr[512];
	int nErrCode = 0; //错误号

	//形成SQL语句
	char szSQLArr[512];
	memset(szSQLArr, 0, 512);
	CString sContent= "abcde";
	//sprintf(szSQLArr, " BEGIN INSERT INTO LOB_TEST(ID, TXT, IMAGE, CONTENT) VALUES(%d, EMPTY_CLOB(), EMPTY_BLOB(), '%s'); COMMIT; END;", nPKValue, sContent);
	sprintf(szSQLArr, " BEGIN INSERT INTO LOB_TEST(ID, TXT, IMAGE, CONTENT) VALUES(seq_content.nextval, EMPTY_CLOB(), EMPTY_BLOB(), '%s'); COMMIT; END;", sContent);

	//准备SQL语句送到Oracle中
	int rc = OCIStmtPrepare(hOCI.phStmt,
		                    hOCI.phErr,
							(text *)szSQLArr,
							(ub4)strlen((char *)szSQLArr),
							(ub4)OCI_NTV_SYNTAX,
							(ub4)OCI_DEFAULT);
	if(OCI_SUCCESS != rc)
	{
		//获取错误信息
		m_oOCIBase.GetOCIErrInfo(hOCI.phErr, nErrCode, szInfoStrArr, 256);
		memset(szErrInfoArr, 0, 512);
		sprintf(szErrInfoArr, "ORA-%d: %s", nErrCode, szInfoStrArr);
		MessageBox(szErrInfoArr, "Oracle出错", MB_OK|MB_ICONSTOP);
		return 0;
	}

	//执行SQL语句
	rc = OCIStmtExecute(hOCI.phService,
		                hOCI.phStmt,
						hOCI.phErr,
						(ub4)1,
						(ub4)0,
						(CONST OCISnapshot *) 0, 
						(OCISnapshot *) 0,
						(ub4)OCI_DEFAULT);
	if(OCI_SUCCESS != rc && OCI_SUCCESS_WITH_INFO != rc)
	{
		m_oOCIBase.GetOCIErrInfo(hOCI.phErr, nErrCode, szInfoStrArr, 256);
		memset(szErrInfoArr, 0, 512);
		sprintf(szErrInfoArr, "ORA-%d: %s", nErrCode, szInfoStrArr);
		MessageBox(szErrInfoArr, "Oracle出错", MB_OK|MB_ICONSTOP);
		return 0;
	}

	//成功,返回
	return 1;
}

//把数据写到pLob指定的位置中
//成功,返回1,否则返回0
int CLOBDlg::WriteLob(char *pszFile, OCIHANDLE hOCI, OCILobLocator *pLob)
{
	CButton *pctrlButt = (CButton *)GetDlgItem(IDC_INFO);
	char szInfoArr[512];
	
	//打开文件
	FILE *pfLob = fopen(pszFile, "rb");
	if(NULL == pfLob)
		return 0;
	
	//把文件指针移到文件结束
	fseek(pfLob, 0L, SEEK_END);

	//获得文件数据的长度
	long nFileLen = ftell(pfLob);
	if(0 >= nFileLen)
	{
		sprintf(szInfoArr, "文件:%s中没有数据!", pszFile);
		pctrlButt->SetWindowText((LPCTSTR)szInfoArr); 
		fclose(pfLob);
		return 0;
	}

	//把文件指针移到文件头部
	fseek(pfLob, 0L, SEEK_SET);

	//从文件中读出一块数据
	ub4 nByteCount = 0;
	if(nFileLen > LOB_MAXBUFFLEN)
		nByteCount = LOB_MAXBUFFLEN;
	else
		nByteCount = (ub4)nFileLen;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -