oracle dmp文件导入 与 blob图片导出

本文详细介绍了如何通过Oracle数据库服务端和客户端版本进行数据迁移,利用ADO.NET技术导出数据,并重点阐述了在数据集中处理包含Blob字段的图片数据的方法,包括连接设置、记录集操作及Blob字段的获取与处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

任务描述:

给定dmp文件和表结构,要求导出其中blob字段的图片,并以其他若干字段组合作为图片文件名。

解决步骤:

1、从 oracle 官网下载 11g 服务端版和客户端版。

2、在服务器上安装 服务端版,并导入 dmp 文件(从10g中导出。)。在控制台中使用imp命令,输入用户名/密码,除了 “要求dmp文件的地方要输入dmp文件的路径文件名” 和 “最后一个选项是否要导入整个dmp文件,输入yes” 外,一路回车即可。如果导入过程有什么错误,做相应修改。比如提示未找到表空间,就另起一个 SQL*PLUS 建一个表空间。

3、在开发机器上安装 客户端版,用 VC + ADO 导出数据。其中有几个需注意的地方。

a、_ConectionPtr对象->Open方法,连接串中的 Data Source 不能只是服务器的 ip,还需要数据库名,应该是 "//192.168.1.11/orcl" 这样的形式。

b、FieldPtr对象->GetItem方法,如果使用索引,要转成 long 或 short 型,不能用 int 型。(这个令人崩溃的BUG 浪费了我很多时间。)

c、_RecordsetPtr对象->Open方法,如果SQL语句比较复杂,比较使用 Left Join关联两个表,最后的";"就要去掉,否则有 ORA-00911 的错误。

代码:

AdoDb.h 

/*
-------------------------------------------------------
类  名:	CAdoDb
文件名:	AdoDb.h / cpp
描  述:	数据库操作。
备  注:	wujp	2013-07-18	初次创建。
-------------------------------------------------------
*/

#pragma once 

#include <windows.h>

#import "C:\\Program Files\\Common Files\\System\\ado\\msado15.dll" no_namespace rename("EOF", "EndOfFile") 

class CAdoDb
{
public:
	CAdoDb();
	virtual ~CAdoDb();

public:
	enum
	{
		MAX_FIELD_NAME_LEN = 100,
		MAX_FIELD_TEXT_LEN = 200,
	};

public:
	BOOL Connenct(const char* pcszHostName, const char* pcszDbName, const char* pcszUserName, const char* pcszPassword);
	//给定 表名 和 字段名 来获取记录集。
	BOOL PrepareRecordset(const char* pcszTableName, const char arrcszFieldName[][MAX_FIELD_NAME_LEN], int nFieldCount);
	//给定 SQL语句 来获取记录集。
	BOOL PrepareRecordset(const char* pcszRecordsetSql);
	//只考虑记录中只有一个 blob字段 的情况。
	BOOL GetCurrentRecord(char arrszFieldValue[][MAX_FIELD_TEXT_LEN], int nFieldCount, BYTE** ppbyBlob, int* pnBlobSize);
	void CloseRecordset();

protected:
	void PrintProviderError(_ConnectionPtr pConnection);
	void PrintComError(_com_error &e);

protected:
	_ConnectionPtr	m_ptrConnect;
	_RecordsetPtr	m_ptrRecordset;
};

AdoDb.cpp

#include "AdoDb.h"

CAdoDb::CAdoDb()
{
	CoInitialize(NULL);
}

CAdoDb::~CAdoDb()
{
	if (m_ptrRecordset)
	{
		if (m_ptrRecordset->GetState() != adStateClosed)
			m_ptrRecordset->Close();
		
		m_ptrRecordset.Release();
	}

	if (m_ptrConnect)
	{
		if (m_ptrConnect->GetState() != adStateClosed)
			m_ptrConnect->Close();
		
		m_ptrConnect.Release();
	}
	
	CoUninitialize();
}

BOOL CAdoDb::Connenct(const char* pcszHostName, const char* pcszDbName, const char* pcszUserName, const char* pcszPassword)
{
	if (!m_ptrConnect)
		m_ptrConnect.CreateInstance(__uuidof(Connection));

	if (!m_ptrRecordset)
		m_ptrRecordset.CreateInstance(__uuidof(Recordset));

	if (!m_ptrConnect || !m_ptrRecordset)
		return FALSE;

	try
	{
		char szConn[1000];
		sprintf_s(szConn, sizeof(szConn), "Provider = 'OraOLEDB.Oracle.1';Data Source = '%s/%s';User ID = '%s';Password = '%s';", pcszHostName, pcszDbName, pcszUserName, pcszPassword);
		m_ptrConnect->Open(szConn, "", "", adConnectUnspecified);
	}
	catch(_com_error& e)
	{
		PrintProviderError(m_ptrConnect);
		PrintComError(e);

		return FALSE;
	}

	return TRUE;
}

//http://msdn.microsoft.com/en-us/library/windows/desktop/ms681557(v=vs.85).aspx

void CAdoDb::PrintProviderError(_ConnectionPtr pConnection)
{
   // Print Provider Errors from Connection object.
   // pErr is a record object in the Connection's Error collection.
   ErrorPtr pErr = NULL;

   if ( (pConnection->Errors->Count) > 0) {
      long nCount = pConnection->Errors->Count;
      // Collection ranges from 0 to nCount -1.
      for ( long i = 0 ; i < nCount ; i++ ) {
         pErr = pConnection->Errors->GetItem(i);
         //printf("\t Error number: %x\t%s", pErr->Number, pErr->Description);
		 char szInfo[500];
		 sprintf_s(szInfo, sizeof(szInfo), "Error number = %x\r\nDesc = %s", pErr->Number, (const char*)pErr->Description);
		 MessageBox(NULL, szInfo, "ADO错误", MB_OK);
      }
   }
}

//http://msdn.microsoft.com/en-us/library/windows/desktop/ms681557(v=vs.85).aspx

void CAdoDb::PrintComError(_com_error &e)
{
	/*
	_bstr_t bstrSource(e.Source());
	_bstr_t bstrDescription(e.Description());

	// Print COM errors. 
	printf("Error\n");
	printf("\tCode = %08lx\n", e.Error());
	printf("\tCode meaning = %s\n", e.ErrorMessage());
	printf("\tSource = %s\n", (LPCSTR) bstrSource);
	printf("\tDescription = %s\n", (LPCSTR) bstrDescription);
	*/

	char szInfo[2000];
	sprintf_s(szInfo, sizeof(szInfo), "Code = %08lx\r\nCode meaning = %s\r\nSource = %s\r\nDescription = %s", 
					e.Error(), e.ErrorMessage(), (const char*)_bstr_t(e.Source()), (const char*)_bstr_t(e.Description()));
	MessageBox(NULL, szInfo, "COM错误", MB_OK);
	return;
}

BOOL CAdoDb::PrepareRecordset(const char* pcszTableName, const char arrcszFieldName[][MAX_FIELD_NAME_LEN], int nFieldCount)
{
	if (nFieldCount < 1)
		return FALSE;
	
	try
	{
		//连接字段名,按逗号分隔。
		char szFieldNameString[1000];
		memset(szFieldNameString, 0, sizeof(szFieldNameString));

		strcpy_s(szFieldNameString, sizeof(szFieldNameString), arrcszFieldName[0]);
		int i;
		for (i=1; i<nFieldCount; i++)
		{
			strcat_s(szFieldNameString, sizeof(szFieldNameString), ",");
			strcat_s(szFieldNameString, sizeof(szFieldNameString), arrcszFieldName[i]);
		}

		char szSql[1000];
		sprintf_s(szSql, sizeof(szSql), "select %s from %s", szFieldNameString, pcszTableName);

		m_ptrRecordset->Open(szSql, m_ptrConnect.GetInterfacePtr(), adOpenStatic, adLockOptimistic, adCmdText);
		m_ptrRecordset->MoveFirst();
	}
	catch(_com_error& e)
	{
		PrintComError(e);
		return FALSE;
	}

	return TRUE;
}

BOOL CAdoDb::PrepareRecordset(const char* pcszRecordsetSql)
{
	try
	{
		m_ptrRecordset->Open(pcszRecordsetSql, m_ptrConnect.GetInterfacePtr(), adOpenStatic, adLockOptimistic, adCmdText);
		m_ptrRecordset->MoveFirst();
	}
	catch(_com_error& e)
	{
		PrintComError(e);
		return FALSE;
	}

	return TRUE;
}

void CAdoDb::CloseRecordset()
{
	m_ptrRecordset->Close();
}

BOOL CAdoDb::GetCurrentRecord(char arrszFieldValue[][MAX_FIELD_TEXT_LEN], int nFieldCount, BYTE** ppbyBlob, int* pnBlobSize)
{
	if (m_ptrRecordset->EndOfFile)
		return FALSE;
	
	try
	{
		//指向当前记录的字段集。
		FieldsPtr ptrFields = m_ptrRecordset->GetFields();
		if (nFieldCount != ptrFields->GetCount())
			return FALSE;

		int i;
		for (i=0; i<nFieldCount; i++)
		{
			//这里一定要先转成 long 或 short。
			//因为如果是 int,_variant_t 的 vt 值就是 VT_INT,值保存在 intVal。
			//而 long/short 的 vt类型是 VT_I4/VT_I2,值保存在 lVal/iVal。
			FieldPtr ptrField = ptrFields->GetItem(_variant_t((long)i));
				
			//字段长度,没什么用,随便看看。
			long lDataSize = ptrField->GetActualSize();
			//字段类型,没什么用,随便看看。
			DataTypeEnum nType = ptrField->GetType();
			//字段名,没什么用,随便看看。
			_bstr_t bstrName = ptrField->GetName();

			if (ptrField->GetAttributes() & adFldLong)
			{
				//这是一个 blob 字段。
				long lDataSize = ptrField->GetActualSize();
				_variant_t varData = ptrField->GetChunk(lDataSize);
				
				if (pnBlobSize)
				{
					*pnBlobSize = lDataSize;
					*ppbyBlob = new BYTE[lDataSize];

					BYTE* pbyData = NULL;
					SafeArrayAccessData(varData.parray, (void**)&pbyData);
					memcpy(*ppbyBlob, pbyData, lDataSize);
					SafeArrayUnaccessData(varData.parray);
				}

				//blob 的数据已放入 ppbyBlob 和 pnBlobSize 参数中,这里只是做个标记。
				strcpy_s(arrszFieldValue[i], MAX_FIELD_TEXT_LEN, "blob");
			}
			else
			{
				_variant_t varValue = ptrField->GetValue();

				//如果字段类型不是字符串类型的,_bstr_t 会把它自动转成 BSTR,再复制的。
				strcpy_s(arrszFieldValue[i], MAX_FIELD_TEXT_LEN, (const char*)_bstr_t(varValue));
			}
		}
	}
	catch(_com_error& e)
	{
		PrintComError(e);
		return FALSE;
	}

	m_ptrRecordset->MoveNext();
	return TRUE;
}

### 回答1: 要导出导入Oracle数据库中的CLOBBLOB数据类型,可以使用以下方法: 1. 使用Oracle自带的expimp工具导出导入整个数据库或特定表的数据。在导出时,使用参数“file=clob_data.dmp”或“file=blob_data.dmp”指定导出文件名。在导入时,使用参数“file=clob_data.dmp”或“file=blob_data.dmp”指定导入文件名。 2. 使用Oracle SQL Developer工具导出导入特定表的数据。在导出时,选择要导出的表,右键点击选择“导出”选项,选择“导出数据”并选择“导出为LOB文件”。在导入时,选择要导入的表,右键点击选择“导入”选项,选择“导入数据”并选择“从LOB文件导入”。 3. 使用PL/SQL代码导出导入CLOBBLOB数据。在导出时,使用SELECT语句查询CLOB或BLOB列的值,并将其写入文件中。在导入时,使用INSERT语句将文件中的值插入到CLOB或BLOB列中。 以上是几种常见的导出导入Oracle数据库中CLOBBLOB数据的方法。具体使用哪种方法取决于具体情况需求。 ### 回答2: Oracle是一个广泛使用的关系型数据库,其中包含了CLOB(字符大对象)BLOB(二进制大对象)类型的数据。这些数据类型通常用于存储大型文本图像等二进制数据。在Oracle中,导出导入CLOBBLOB数据是非常常见的任务。本文将介绍如何导出导入这些类型的数据。 首先,我们需要了解Oracle提供的导出工具是expexpdpexp是旧版工具,而expdp是新版工具。在导出CLOBBLOB数据时,我们建议使用expdp,因为它是专门为大量导出数据而设计的。下面我们来看看导出CLOB数据的方法: 1. 使用expdp导出 使用expdp命令导出CLOB数据需要指定以下参数: - expdp system/password tables=table_name directory=directory_name dumpfile=file_name.dmp lob_file=file_name.log EXCLUDE=STATISTICS 其中table_name是要导出的表名,directory_name是导出文件的路径,file_name是导出文件的名称,lob_file是LOB类型的文件的名称。 2. 使用SQL*Plus导出 我们也可以使用SQL*Plus命令导出CLOB数据。以下是步骤: 1)使用SQL*Plus连接到Oracle数据库。 2)使用以下命令在本机上创建目录 OBJECT_DIR: CREATE OR REPLACE DIRECTORY OBJECT_DIR AS 'C:\TEMP'; 3)使用以下命令导出CLOB数据: SET LONG 10000 SET PAGESIZE 0 SET LINESIZE 1000 SET FEEDBACK OFF SPOOL CLOB_Export.sql SELECT 'SELECT ' || column_name || ' FROM ' || table_name || ' WHERE ' || where_clause || ';' FROM all_tab_cols WHERE data_type = 'CLOB' AND table_name = 'TABLE_NAME'; SPOOL OFF 4)使用以下命令将生成的SQL脚本文件CLOB_Export.sql导出到本地目录: exp userid=username/password file=dumpfile.dmp owner=owner_name log=clob_export.log 接下来我们会介绍如何导入CLOBBLOB数据。 1. 使用impdp导入 使用impdp命令导入CLOB数据需要指定以下参数: - impdp system/password directory=directory_name dumpfile=file_name.dmp logfile=file_name.log tables=table_name 其中directory_name是导入文件的路径,file_name是导入文件的名称,table_name是要导入数据的表的名称。 2. 使用SQL*Plus导入 我们也可以使用SQL*Plus命令导入CLOB数据。以下是步骤: 1)使用SQL*Plus连接到Oracle数据库。 2)使用以下命令在本机上创建LOB的目录 LOB_DIR: CREATE OR REPLACE DIRECTORY LOB_DIR AS 'C:\TEMP'; 3)使用以下命令在Oracle中创建LOB表: CREATE TABLE lob_table ( lob_column CLOB ); 4)使用以下命令将LOB类型的文件loaded_file.xml导入到LOB表中: INSERT INTO lob_table (lob_column) VALUES (EMPTY_CLOB()); SELECT lob_column FROM lob_table FOR UPDATE; DECLARE infile BFILE :=BFILENAME('OBJECT_DIR', 'loaded_file.xml'); lob_loc CLOB; BEGIN DBMS_LOB.OPEN(lob_column, DBMS_LOB.LOB_READWRITE); DBMS_LOB.LOADFROMFILE(lob_column, infile, DBMS_LOB.GETLENGTH(infile)); DBMS_LOB.CLOSE(lob_column); COMMIT; END; / 以上是导出导入CLOB/BLOB数据的两种方法,根据实际情况可以选择使用expdp、impdp或SQL*Plus导出导入。然而在导入CLOB/BLOB时,需要特别注意数据库版本以及LOB大小限制等问题。 ### 回答3: 在Oracle中,CLOBBLOB是用来存储大文本二进制数据的数据类型。有时候我们需要对这些数据进行导入导出。在这篇文章中,我会介绍如何将CLOBBLOB数据导入导出导出CLOB/BLOB数据 在Oracle中,可以使用DBMS_LOB包来导出CLOBBLOB数据。首先,我们需要使用SELECT语句来查询需要导出的数据。查询的结果会以一个CLOB或BLOB对象的形式存在,然后我们可以把这个对象导出到一个文件中。以下是导出CLOBBLOB对象到文件中的步骤: 1.查询需要导出的数据 例如,我们可以使用以下SELECT语句来查询一个CLOB表中的数据: SELECT clob_column FROM clob_table; 2.将查询结果存储到变量中 为了方便将查询结果导出文件中,我们需要将查询结果存储到一个变量中。我们可以使用PL/SQL或SQL*Plus来完成这个任务。以下是一个PL/SQL的例子: DECLARE my_data CLOB; BEGIN SELECT clob_column INTO my_data FROM clob_table; END; 3.将变量的值导出文件中 使用DBMS_LOB包中的函数,可以将变量的值导出文件中,以下是一个导出CLOB数据的例子: DECLARE my_data CLOB; my_file UTL_FILE.FILE_TYPE; BEGIN SELECT clob_column INTO my_data FROM clob_table; my_file := UTL_FILE.FOPEN('MY_DIR', 'my_file.txt', 'w'); DBMS_LOB.FILEEXPORT(my_file, my_data); UTL_FILE.FCLOSE(my_file); END; 注意: - 'MY_DIR'是Oracle指定的一个目录,需要在数据库中提前定义。 - 'my_file.txt'是导出文件的名称 - 'w'表示以覆盖模式写入文件 这个例子将会把查询出来的CLOB数据导出为txt文件导入CLOB/BLOB数据 同样的,我们可以使用DBMS_LOB包来导入CLOBBLOB数据。以下是导入CLOBBLOB数据的步骤: 1.读取文件内容 使用UTL_FILE包中的函数,可以读取文件的内容到一个变量中,例如以下SQL*Plus的命令: DEFINE my_file='my_file.txt' DECLARE my_data CLOB; my_file UTL_FILE.FILE_TYPE; BEGIN my_file := UTL_FILE.FOPEN('MY_DIR', '&my_file', 'r'); UTL_FILE.GET_LINE(my_file, my_data); UTL_FILE.FCLOSE(my_file); END; 注意: - 'my_file.txt'是要导入到数据库的文件名称 - MY_DIR是Oracle指定的一个目录,需要在数据库中提前定义。 2.将变量的值导入到数据库中 使用INSERT语句将变量的值插入到CLOB表中,例如以下的SQL*Plus命令: INSERT INTO clob_table (clob_column) VALUES (my_data); 注意: 在Oracle中,插入CLOBBLOB数据时,要使用专门的函数,例如: INSERT INTO clob_table (clob_column) VALUES (TO_LOB('some text')); 以上就是导出导入CLOB/BLOB数据的步骤。当然,在实际操作中可能会遇到各种各样的问题,我们需要仔细阅读相关的文档,查找正确的解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值