62,074
社区成员
发帖
与我相关
我的任务
分享
namespace TestOracleConnection
{
class Program
{
static void Main(string[] args)
{
string oraclePath = Environment.CurrentDirectory + @"\Oracle\";
// 此处被注释的代码为ORACLE的环境设置。下文说明作用。
//Environment.SetEnvironmentVariable("PATH", oraclePath, EnvironmentVariableTarget.Process);
//Environment.SetEnvironmentVariable("ORACLE_HOME", oraclePath, EnvironmentVariableTarget.Process);
//Environment.SetEnvironmentVariable("LD_LIBRARY_PATH", oraclePath, EnvironmentVariableTarget.Process);
//Environment.SetEnvironmentVariable("NLS_LANG", "SIMPLIFIED CHINESE_CHINA.ZHS16GBK", EnvironmentVariableTarget.Process);
//Environment.SetEnvironmentVariable("TNS_ADMIN", oraclePath, EnvironmentVariableTarget.Process);
string connStr = ConfigurationManager.AppSettings["OracleConnectionString"];
string envStr = Environment.GetEnvironmentVariable("PATH");
Console.WriteLine(connStr + "\r\n");
Console.WriteLine(envStr + "\r\n");
Console.WriteLine(oraclePath + "\r\n");
using (OracleConnection conn = new OracleConnection(connStr))
{
try
{
conn.Open();
string sqlStr = "SELECT * FROM EMP";
using (OracleCommand comm = new OracleCommand(sqlStr, conn))
{
using (OracleDataReader rdr = comm.ExecuteReader())
{
while (rdr.Read())
{
Console.Write(rdr[0].ToString() + "\t");
Console.Write(rdr[1].ToString() + "\t");
Console.Write(rdr[2].ToString() + "\t");
Console.Write(rdr[3].ToString() + "\t");
Console.WriteLine(rdr[4].ToString());
}
}
}
Console.WriteLine("Successful!\r\n");
}
catch (Exception ex)
{
Console.WriteLine("ERROR " + ex.ToString() + "\r\n");
}
finally
{
conn.Dispose();
}
}
Console.ReadKey();
}
}
}
一、 B服务器中没有ORACLE的任何组件和客户端
如果服务器中没有安装任何的ORACLE客户端组件,在将测试程序发布到服务器B时,需要同时复制ORACLE的基本类库到测试程序相同的目录中:
在复制ORACLE类型时需要注意测试程序引用Oracle.DataAccess时的版本(即X64或X32)。
如果在VS2013中编译时的CPU是ANY CPU则根据服务器的操作系统决定Oracle.DataAccess的版本,如果是X64则需要引用X64的Oracle.DataAccess,X86则需要引用X32的Oracle.DataAccess。
在确定Oracle.DataAccess的版本后,再复制和Oracle.DataAccess版本对应的Oracle的dll文件。
如果Oracle.DataAccess的版本为2.12x.x.x(即Oracle12g),如果测试程序引用的是这个版本,则服务器需要安装.net 4.0。需要复制的文件为:
oci.dll
ocijdbc12.dll
ociw32.dll
orannzsbb12.dll
Oracle.DataAccess.dll
oraocci12.dll
oraociei12.dll
oraons.dll
OraOps12.dll
msvcr100.dll
如果Oracle.DataAccess的版本为2.11x.x.x(即Oracle11g)需要复制的文件为:
oci.dll
ocijdbc11.dll
ociw32.dll
Oracle.DataAccess.dll
oraocci11.dll
oraociei11.dll
OraOps11w.dll
msvcr100.dll
如果Oracle.DataAccess的版本为2.10x.x.x(即Oracle11g)需要复制的文件为:
classes12.jar
oci.dll
ocijdbc10.dll
ociw32.dll
ojdbc14.jar
Oracle.DataAccess.dll
orannzsbb10.dll
oraocci10.dll
oraociei10.dll
OraOps10.dll
msvcr100.dll
注意: msvcr100.dll这个文件比较特殊,这个文件是系统文件,Oracle12g的连接驱动需要依赖这个文件。一般操作系统中都有这个文件,但如果没有这个文件,则在使用Oracle12g版本(其它版本:如果Oracle.DataAccess不是12g版本而oci.dll是12g版本的测也需要这个文件)的Oracle.DataAccess测试时会报找不到OraOps12.dll的异常,
具体为,如果VS2013编译的程序是64bit的,则需要64bit的msvcr100.dll,如果编译的程序是32bit的,则需要32位的msvcr100.dll。如果系统中没有对应的文件,则会报找不到OraOps12.dll的异常。
msvcr100.dll文件在系统中的位置是:%systemdir%\System32和C:\Windows\SysWOW64各有一个。
System32中的是64bit类库,12g版本的64bit的oci.dll需要依赖这个库文件。
SysWOW64中的是32bit类库,12g版本的32bit的oci.dll需要依赖这个库文件。
如果%systemdir%\System32目录中没有msvcr100.dll这个库文件,在运行64bit测试程序时会弹出msvcr100.dll文件丢失的错误信息,
如果和C:\Windows\SysWOW64中没有msvcr100.dll这个库文件,在运行32bit的测试程序时会弹出msvcr100.dll文件丢失的错误信息,
如果%systemdir%\System32目录有msvcr100.dll库文件但C:\Windows\SysWOW64中没有,在运行64bit测试程序时正常,但运行32bit测试程序时会报找不到OraOps12.dll的异常信息,反之一样。
所以为了保险起见,最好将对应的msvcr100.dll文件一起复制到测试程序的目录中或系统目录中。
测试程序中被注释的ORACLE环境设置的代码说明:
string oraclePath = System.Windows.Forms.Application.StartupPath + @"\oracle"; //这一句取得了oracle 驱动文件夹的位置,也就是放oci.dll的地方。
Environment.SetEnvironmentVariable("PATH", oraclePath,EnvironmentVariableTarget.Process); //这一句设置环境变量“PATH”,写入oracle驱动所在的文件夹,第三个参数表示这个PATH只在当前进程起作用,不会修改电脑本身。
注意:如果你用到某些外部程序,还有其他PATH变量要设置,在这里加入就行了。具体方法参见.net相关文档。
Environment.SetEnvironmentVariable("NLS_LANG", "SIMPLIFIED CHINESE_CHINA.ZHS16GBK", EnvironmentVariableTarget.Process); //这一句,设置Oracle在通讯过程中使用的语言和字符集。
我的项目用的是上面的字符集,对应到你的项目,可用SQL语句去oracle数据库中查询。这个语言和字符集一定要和服务器一致,否则可能会出现乱码甚至无法连接。可能会用到如下SQL语句:
//select userenv('language') from dual; 查询服务端字符集,用来设置上面的参数。
//select * from nls_database_parameters;//服务器字符集
//select * from nls_instance_parameters;//ora文件定义字符集
//select * from nls_session_parameters; //会话字符集
理论上,经过上面的设置,程序可以使用Path指定的目录下的Oracle驱动了,这里要注意的还有就是连接数据库的方式,上面的修改并不能保证你可以使用tns名来连接,
因此在app.config中修改connectionString为:
Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=服务器IP地址)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=服务器上的数据库实例名)));User Id=数据库用户名;Password=数据库密码;
这个主要是把“Data Source”这部分直接用tcp/ip字符串方式替换了(通常Data Source是写tns名称的)。
如果需要使用tns名称来访问oracle数据库,那么还要做以下工作。
在程序设置环境变量的地方,加入:
Environment.SetEnvironmentVariable("TNS_ADMIN", oraclePath, EnvironmentVariableTarget.Process);
在程序的oraclePath参数所指定的文件夹下增加tnsnames.ora,并将tns名称的配置写到里边去。
连接字符串里应该可以使用tns名称了。
在安装了ODAC的情况,即一般不需要做这些工作。
二、 B服务器中安装了ORACLE的ODAC。
如果B服务器安装了ODAC,那么就简单了,需要如下几步:
1、 检查服务器上安装的ODAC是64bit的还是32bit的。
2、 在编译测试程序时注意选择CPU模式,根据服务器上安装的ODAC的版本选择将程序编译成为64bit或32bit,并正确引用对应的Oracle.DataAccess的版本。
3、 将测试程序复制到服务器上即可运行。
可能出现的问题:
1、 如果服务器上安装了ODAC,ODAC会在.NET的GAC中注册Oracle.DataAccess类库,由于.NET程序在使用.net类库时会优先使用GAC中注册的类库,
所以如果将测试程序部署到安装好ODAC的服务器上时,不管理测试程序引用的Oracle.DataAccess是什么版本,程序运行时都会优先使用GAC中注册的Oracle.DataAccess。
而如果测试程序中使用代码设定了程序运行时的环境变量,比如使用了如下代码:
string oraclePath = System.Windows.Forms.Application.StartupPath + @"\oracle"; //这一句取得了oracle 驱动文件夹的位置,也就是放oci.dll的地方。
Environment.SetEnvironmentVariable("PATH", oraclePath,EnvironmentVariableTarget.Process);
则需要在服务器中从ODAC的安装目录复制Oracle的驱动文件到代码指定的PATH目录中,而不是复制在开发机器上的与Oracle.DataAccesss对应的Oracle驱动文件。
2、 .net使用GAC注册的类库时,需要判别注册的类库的版本,公钥号,平台等信息。所以如果服务器中没有安装和应用程序运行平台对应的ODAC,则需要将应用程序对应平台的Oracle驱动类库文件一起复制到服务器的应用程序安装目录或程序中指定的环境变量目录中,
程序运行时会根据程序的运行平台从GAC中查找和平台相关的Oracle.DataAccess类库,没有时从程序安装目录或程序指定环境的目录中调用类库。
三、 注意事项和TNS配置:
如果程序中设置了环境变量,则需要根据环境变量的设定将Oracle驱动文件复制到正确的目录中,比如:在程序中使用如下代码设定环境变量,在复制Oracle驱动文件时,就是不将文件复制到应用程序相同的目录中了,而是将文件复制到oraclePath变量指定的目录位置。
string oraclePath = System.Windows.Forms.Application.StartupPath + @"\oracle"; //这一句取得了oracle 驱动文件夹的位置,也就是放oci.dll的地方。
Environment.SetEnvironmentVariable("PATH", oraclePath,EnvironmentVariableTarget.Process); //这一句设置环境变量“PATH”,写入oracle驱动所在的文件夹,第三个参数表示这个PATH只在当前进程起作用,不会修改电脑本身。
TNS配置:
在服务器不安装ODAC时,如果需要使用TNS连接数据库,则需要在写测试程序时设定Oracle的TNS环境变量或在操作系统的环境变量中加入TNS的配置。
程序中设定TNS的代码如下:
Environment.SetEnvironmentVariable("TNS_ADMIN", oraclePath, EnvironmentVariableTarget.Process); //这句的意思是在当前进程中加入一个环境变量为TNS_ADMIN的设定。
如果不想在写程序时设定也可以在操作系统中的环境变量中加入TNS_ADMIN的设定。
如果安装了ODAC,则不需要在程序中写关闭TNS的代码,只需要在ODAC的安装目录的Network\admin目录中添加一个tnsnames.ora文件,并写好TNS的配置即可。