背景:
由于项目要求,需要将数据从一个DB(DB1)导入到另一个DB(DB2)中。两个DB有相同的表结构,只是字段名字不一样:DB1中的字段是汉字的,而DB2中的字段是英文的。需要建立两个表之间的连接,再从DB1中检索数据插入到DB2中。因此,问题的关键在于在DB1中建立同DB2的连接(也可以在DB2中建立同DB1的连接)。Oracle提供了DataBase Link来连接两个DB,从而方便的实现跨DB的操作。
技术点摘要:
从本质上来说DBLink也是Oracle数据库中的一个对象。我们可以想创建其它Oracle 对象一样创建和删除DBLink。只是有两点需要注意:一是权限问题,登陆的用户必须要有创建DBLink的权限。二是创建的DBLink的访问权限,如果创建了一个非管理员用户只能创建具有公有(public)访问权限的DBLink。
实现细节:
用户有了权限后就可以创建DBLink了:
首先要确保你的DB能正确的连接。连接一个DB有两个办法:1是在本地安装Oracle的客户端,在TNSNAMES.ora中配置对远程机器的连接。2是直接连接远程的数据库服务器。如:假设在IP为172.16.97.131的机器上有一个DB服务器,服务名为OraServer,那也可以这样指定连接:172.16.97.131/OraServer。而不用在本地配置TNS。不管采用哪种方式必须保证你的机器能正常连接到DB1和DB2。
然后就是确保连接的用户要有创建DBLink的权限。如果你需要用DB1连接DB2,那你登陆DB1的用户必须要有创建DBLink的权限。可以用SYSDBA的身份登陆DB执行下面的语句为指定用户授权:
grant create public database link to username
CREATE PUBLIC DATABASE LINK LKNAME
CONNECT TO USERNAME
IDENTIFIED BY PASSWORD
USING ‘DBSERVER’
CONNECT TO USERNAME
IDENTIFIED BY PASSWORD
USING ‘DBSERVER’
建立连接后可以用语句查看创建的DBLink下面的 使用完了以后要删除已创建的DBLink:
select db_link from dba_db_links;
DROP PUBLIC DATABASE LINK LKNAME
需要说明的是,如果你创建的不是PUBLIC的DBLINK,那只能有创建者删除自己创建的DBLINK,而非管理员权限的用户创建的DBLink只能由SYS用户删除
/// <summary>
/// DBリック作成
/// </summary>
/// <returns>エラーがある場合、エラーメッセージを戻す</returns>
private string CreateDBLink()
{
try
{
//DB接続処理
if (cnnDestDB.State != ConnectionState.Open)
{
cnnDestDB.Open();
}
OracleCommand cmdCreateLink = new OracleCommand();
cmdCreateLink.Connection = cnnDestDB;
//DBリックSQL文
//CREATE PUBLIC DATABASE LINK LINKNAME CONNECT TO USERNAME IDENTIFIED BY PASSWORD USING 'SID'
string strCreateLink = "CREATE PUBLIC DATABASE LINK " + strLinkName + " CONNECT TO " + txtUserId2.Text.Trim() + " IDENTIFIED BY " + txtPassWord2.Text + " USING '" + txtSid2.Text.Trim() + "'";
cmdCreateLink.CommandText = strCreateLink;
//DBリック作成
cmdCreateLink.ExecuteNonQuery();
cnnDestDB.Close();
return string.Empty;
}
catch (Exception ex)
{
if (cnnDestDB.State != ConnectionState.Closed)
{
cnnDestDB.Close();
}
return ex.Message;
}
}
/// <summary>
/// DBリックの削除
/// </summary>
/// <returns>エラーがある場合、エラーメッセージを戻す</returns>
private string DeleteDBLink()
{
try
{
//DB接続処理
if (cnnDestDB.State != ConnectionState.Open)
{
cnnDestDB.Open();
}
OracleCommand cmdDropLink = new OracleCommand();
cmdDropLink.Connection = cnnDestDB;
//DBリックSQL文
//DROP PUBLIC DATABASE LINK LINKNAME
string strDropLink = "DROP PUBLIC DATABASE LINK " + strLinkName;
cmdDropLink.CommandText = strDropLink;
//DBリック削除
cmdDropLink.ExecuteNonQuery();
cnnDestDB.Close();
return string.Empty;
}
catch (Exception ex)
{
if (cnnDestDB.State != ConnectionState.Closed)
{
cnnDestDB.Close();
}
return ex.Message;
}
}
/// DBリック作成
/// </summary>
/// <returns>エラーがある場合、エラーメッセージを戻す</returns>
private string CreateDBLink()
{
try
{
//DB接続処理
if (cnnDestDB.State != ConnectionState.Open)
{
cnnDestDB.Open();
}
OracleCommand cmdCreateLink = new OracleCommand();
cmdCreateLink.Connection = cnnDestDB;
//DBリックSQL文
//CREATE PUBLIC DATABASE LINK LINKNAME CONNECT TO USERNAME IDENTIFIED BY PASSWORD USING 'SID'
string strCreateLink = "CREATE PUBLIC DATABASE LINK " + strLinkName + " CONNECT TO " + txtUserId2.Text.Trim() + " IDENTIFIED BY " + txtPassWord2.Text + " USING '" + txtSid2.Text.Trim() + "'";
cmdCreateLink.CommandText = strCreateLink;
//DBリック作成
cmdCreateLink.ExecuteNonQuery();
cnnDestDB.Close();
return string.Empty;
}
catch (Exception ex)
{
if (cnnDestDB.State != ConnectionState.Closed)
{
cnnDestDB.Close();
}
return ex.Message;
}
}
/// <summary>
/// DBリックの削除
/// </summary>
/// <returns>エラーがある場合、エラーメッセージを戻す</returns>
private string DeleteDBLink()
{
try
{
//DB接続処理
if (cnnDestDB.State != ConnectionState.Open)
{
cnnDestDB.Open();
}
OracleCommand cmdDropLink = new OracleCommand();
cmdDropLink.Connection = cnnDestDB;
//DBリックSQL文
//DROP PUBLIC DATABASE LINK LINKNAME
string strDropLink = "DROP PUBLIC DATABASE LINK " + strLinkName;
cmdDropLink.CommandText = strDropLink;
//DBリック削除
cmdDropLink.ExecuteNonQuery();
cnnDestDB.Close();
return string.Empty;
}
catch (Exception ex)
{
if (cnnDestDB.State != ConnectionState.Closed)
{
cnnDestDB.Close();
}
return ex.Message;
}
}