本方法优点: 1、程序内集成Oracle客户端,无需用户自行进行配置
本方法缺点: 2、增加程序包的体积(Oracle instant client本身有几十兆大小)
下面说一下如何实现。
- 0、首先,从Oracle网站上下载对应版本的Oracle instant client包,网址在这里 http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html 由于是Windows程序,只需要下载Win32或64版本就行了。
- 1、下载来的.zip压缩包,解压后应该有如下文件:(我使用的是11G版本,其他版本可能略有不用)
- 2、在你的工程根目录下新建一个”Oracle”的文件夹(其实名字和位置随便定),然后将上述文件拷贝到里边,并在Visual Studio中添加这个文件夹及文件们。保证你的解决方案里能看到它们。
- 3、在Visual Studio IDE的“解决方案资源管理器”里,打开Oracle文件夹,选中里边所有的文件,在“属性”“复制到输出目录”里设置“如果较新则复制”,这样在编译或者发布程序的时候,Oracle文件夹会随着发布到exe所在的地方,部署时候就不会出现找不到Oracle库的情况。
- 4、按照网上的大多数教程,这个时候就需要在widnows环境变量里边添加东西了。其实这一步不是必须的,因为考虑到不同的客户环境,有可能用户没有权限在他的计算机上操作这些,那么我们把设置Oracle环境变量放到程序里来做。那么在你初始化程序之后使用Oracle之前,需要添加如下代码:
string oraclePath = System.Windows.Forms.Application.StartupPath + @"\oracle"; Environment.SetEnvironmentVariable("PATH", oraclePath,EnvironmentVariableTarget.Process); Environment.SetEnvironmentVariable("NLS_LANG", "SIMPLIFIED CHINESE_CHINA.ZHS16GBK", EnvironmentVariableTarget.Process);
解释一下上面的代码: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; //会话字符集
- 5、理论上,经过上面的设置,你的程序就可以使用内置到exe目录下的Oracle驱动了,这里要注意的还有就是连接数据库的方式,上面的修改并不能保证你可以使用tns名来连接,因此连接字符串要做如下修改:
在app.config中修改connectionString为
Persist Security Info=True;User ID=数据库用户名;Password=数据库密码;Unicode=True;Data Source= (DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = 服务器IP地址)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = 服务器上的数据库实例名)));
这个主要是把“Data Source”这部分直接用tcp/ip字符串方式替换了(通常Data Source是写tns名称的) - 6、好了,运行你的程序试试看吧。
如果你tns名称来访问oracle数据库,那么还要做以下工作。
- a.在程序的Oracle文件夹下增加tnsnames.ora,并将tns名称的配置写到里边去。
- b.在程序设置环境变量的地方,加入
Environment.SetEnvironmentVariable("TNS_ADMIN", oraclePath,EnvironmentVariableTarget.Process);
- c.连接字符串里应该可以使用tns名称了
整体代码如下:
// 这一句取得了oracle 驱动文件夹的位置,也就是放oci.dll的地方。 string oraclePath = System.Windows.Forms.Application.StartupPath + @"\ORCLconn"; // //这一句设置环境变量“PATH”,写入oracle驱动所在的文件夹, // //第三个参数表示这个PATH只在当前进程起作用,不会修改电脑本身。 // //注意:如果你用到某些外部程序,还有其他PATH变量要设置,在这里加入就行了。具体方法参见.net相关文档。 ///当系统还使用其他软件的环境变量时则需要先获取本机电脑上的环境变脸结合Oracle环境变量一起使用。 string s = Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Machine); Environment.SetEnvironmentVariable("PATH", s + ";" + oraclePath, EnvironmentVariableTarget.Process); // //这一句,设置Oracle在通讯过程中使用的语言和字符集 Environment.SetEnvironmentVariable("NLS_LANG", "SIMPLIFIED CHINESE_CHINA.ZHS16GBK", EnvironmentVariableTarget.Process); // //在程序的Oracle文件夹下增加tnsnames.ora,并将tns名称的配置写到里边去。 // //b.在程序设置环境变量的地方c.连接字符串里应该可以使用tns名称了 Environment.SetEnvironmentVariable("TNS_ADMIN", oraclePath, EnvironmentVariableTarget.Process);