C# 调用 Oracle
C# 调用 Oracle 是如此尴尬
>System.Data.OracleClient.dll —— .Net 自带的 已经 过时作废。
>要链接 Oracle 服务器,必须在 本机安装 Oracle 客户端 —— 而 SQLServer 不需要安装客户端。
win32_11gR2_client.zip(652M)
win64_11gR2_client.zip(587M)
>Oracle.DataAccess.dll—— Oracle 官方 提供的.Net 程序集【在安装目录 ODP.NET 中】。
Oracle.DataAccess.dll 严格区分 x32、x64 —— 程序集 不是 AnyCPU。
x32 客户端 只包括 x32 的 Oracle.DataAccess.dll。
x64 客户端 只包括 x64 的 Oracle.DataAccess.dll。
发布程序的时候,就很容易在这个地方 出现问题。
>Oracle.ManagedDataAccess.dll —— Oracle 官方 提供的.Net 程序集
支持 AnyCPU
不需要安装 600M 的客户端
Oracle.ManagedDataAccess —— 你值得拥有。
>Oracle.DataAccess.dll 和 Oracle.ManagedDataAccess.dll 用法完全一样。
支持的 SQL脚本语法一样。
SQL 脚本 不能以 分号 结尾。
一样的:这也不支持,那也不支持。
C# 调用 Oracle 语法限制
>Oracle 不支持 自增主键 —— 自增主键 需要使用 触发器。
>Oracle 表名,字段名 不能超过30个字符。
>脚本 参数化, 关键符为 : —— SQLServer 关键符为 @
>脚本 名称区域, 关键符为 "表名"."字段名" —— SQLServer 关键符为 [表名].[字段名]
警告:脚本中 不建议 将 数据库名、表名、字段名 用 引号括起来 —— 后果很严重。
>支持 多条 修改语句 同时执行:


- BEGIN
- UPDATE TB_Test SET Name='INK';
- DELETE TB_Test WHERE Name='INK';
- INSERT INTO TB_Test(Name) VALUES('INK');
- END;


>不支持 多条 查询语句,得到 DataSet —— 支持 单一查询得到 DataSet。
>支持 ExecuteScalar —— 但是 执行脚本 必须是 单条脚本。
>不支持 插入&查询 自增列—— SQLServer 支持 INSERT INTO…. SELECT@@IDENTITY
警告:即使使用 触发器 实现 自增ID,以下语法也 无法执行:


- BEGIN
- INSERT INTO TB_Test(Name) VALUES('INK'); --先执行 插入
- SELECT MAX(ID) FROMTB_Test; --再执行 查询 最大ID
- END


C# 调用 Oracle 的死结 在于:不支持 多条 非影响SQL脚本同时执行。
有鉴于此,自己随手写了一个OracleHelper.cs
>之前 Oracle 脚本, 自然是 支持的。
>多条 Oracle 脚本,用 ; 分割 —— 即能支持 多条SQL脚本。
>避开了 SQLServer 迁移 Oracle 过程中,出现的脚本不兼容。
>多条SQL脚本将自动开启 数据库事务,确保 绝对正确。
>支持 多条SELECT返回 多DataTable的 DataSet。
>支持 插入&查询自增列(触发器实现的 自增列)
Oracle 全托管程序集 Oracle.ManagedDataAccess.dll
>不再需要安装 600M 的客户端,只需要 单纯引用程序集 就行。
>Oracle.ManagedDataAccess.dll 只是简化了 安装部署,支持 AnyCPU。
>测试通过,但是 功能和 Oracle.DataAccess.dll 功能一样:
.net C# SqlHelper for Oracle
适用于Oracle的sqlhelper
需要使用ODP.Net,引用Oracle.DataAccess.dll 推荐安装ODAC
代码如下:

- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Reflection;
- using System.Data;
- using System.Configuration;
- using Oracle.DataAccess.Client;
- namespace DAL
- {
- public static class SqlHelper
- {
- #region 样本
- //标准连接-SSPI
- private static readonly string defaultConnectString = "Data Source=ORCL;Integrated Security=SSPI;";
- //标准连接
- //private static readonly string defaultConnectString = "Data Source=ORCL;User Id=UPDM;Password=1234;";
- //标准链接
- //private static readonly string defaultConnectString = "Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=orcl)));User Id=system;Password=1234;";
- #endregion
- #region 变量
- private static OracleConnection _con = null;
- public static string _constr = ConfigurationManager.ConnectionStrings["orcl"].ToString();
- #endregion
- #region 属性
- public static string constr
- {
- get
- {
- if (_constr == null||_constr.Equals(String.Empty))
- {
- _constr = defaultConnectString;
- }
- return _constr;
- }
- set
- {
- _constr = value;
- }
- }
- /// <summary>
- /// 获取或设置数据库连接对象
- /// </summary>
- public static OracleConnection Con
- {
- get
- {
- if (SqlHelper._con == null)
- {
- SqlHelper._con = new OracleConnection();
- }
- if (SqlHelper._con.ConnectionString == null || SqlHelper._con.ConnectionString.Equals(string.Empty))
- {
- SqlHelper._con.ConnectionString = SqlHelper.constr;
- }
- return SqlHelper._con;
- }
- set
- {
- SqlHelper._con = value;
- }
- }
- #endregion
- #region 方法
- /// <summary>
- /// 执行并返回第一行第一列的数据库操作
- /// </summary>
- /// <param name="commandText">Sql语句或存储过程名</param>
- /// <param name="commandType">Sql命令类型</param>
- /// <param name="param">Oracle命令参数数组</param>
- /// <returns>第一行第一列的记录</returns>
- public static int ExecuteScalar(string commandText, CommandType commandType, params OracleParameter[] param)
- {
- int result = 0;
- try{
- using (OracleCommand cmd = new OracleCommand(commandText, SqlHelper.Con))
- {
- try
- {
- cmd.CommandType = commandType;
- if (param!=null)
- {
- cmd.Parameters.AddRange(param);
- }
- SqlHelper.Con.Open();
- string x = cmd.CommandText;
- result = Convert.ToInt32(cmd.ExecuteScalar());
- }
- catch
- {
- result = -1;
- }
- }
- }
- finally
- {
- if (SqlHelper.Con.State != ConnectionState.Closed)
- {
- SqlHelper.Con.Close();
- }
- }
- return result;
- }
- /// <summary>
- /// 执行不查询的数据库操作
- /// </summary>
- /// <param name="commandText">Oracle语句或存储过程名</param>
- /// <param name="commandType">Oracle命令类型</param>
- /// <param name="param">Oracle命令参数数组</param>
- /// <returns>受影响的行数</returns>
- public static int ExecuteNonQuery(string commandText, CommandType commandType, params OracleParameter[] param)
- {
- int result = 0;
- try
- {
- using (OracleCommand cmd = new OracleCommand(commandText, SqlHelper.Con))
- {
- try
- {
- cmd.CommandType = commandType;
- if (param!=null)
- {
- cmd.Parameters.AddRange(param);
- }
- SqlHelper.Con.Open();
- result = cmd.ExecuteNonQuery();
- }
- catch
- {
- result = -1;
- }
- }
- }
- finally
- {
- if (SqlHelper.Con.State != ConnectionState.Closed)
- {
- SqlHelper.Con.Close();
- }
- }
- return result;
- }
- /// <summary>
- /// 获取数据表
- /// </summary>
- /// <param name="commandText">select命令</param>
- /// <param name="param">参数表</param>
- /// <returns></returns>
- public static DataTable GetDataTable(string commandText,params OracleParameter[] param)
- {
- DataTable result = new DataTable();
- try
- {
- using (OracleCommand cmd = new OracleCommand(commandText, SqlHelper.Con))
- {
- cmd.Parameters.AddRange(param);
- try {
- OracleDataAdapter adapter = new OracleDataAdapter(cmd);
- adapter.Fill(result);
- }
- catch
- {
- result = null;
- }
- }
- }
- finally
- {
- if (SqlHelper.Con.State != ConnectionState.Closed)
- {
- SqlHelper.Con.Close();
- }
- }
- return result;
- }
- public static int GetNextValueInSequence(string sequenceName)
- {
- if (ExecuteScalar("select count(*) from user_objects where OBJECT_NAME=:seqName", CommandType.Text, new OracleParameter(":seqName",sequenceName)) > 0)
- {
- return ExecuteScalar("select " + sequenceName + ".nextval from dual", CommandType.Text);
- }
- else
- {
- return -1;
- }
- }
- /// <summary>
- /// 事务模式执行多行非查询语句
- /// </summary>
- /// <param name="commandText">sql语句</param>
- /// <param name="param">参数</param>
- /// <returns>受影响行数</returns>
- public static int ExecuteNonQueryTransaction(string commandText, List<OracleParameter[]> param)
- {
- int result = 0;
- try
- {
- using (OracleCommand cmd = new OracleCommand(commandText, SqlHelper.Con))
- {
- SqlHelper.Con.Open();
- cmd.Transaction = cmd.Connection.BeginTransaction();
- try
- {
- foreach (OracleParameter[] par in param)
- {
- cmd.Parameters.Clear();
- cmd.Parameters.AddRange(par);
- result += cmd.ExecuteNonQuery();
- }
- cmd.Transaction.Commit();
- }
- catch
- {
- result = -1;
- try
- {
- cmd.Transaction.Rollback();
- }
- catch
- {
- result = -2;
- }
- }
- }
- }
- finally
- {
- if (SqlHelper.Con.State != ConnectionState.Closed)
- {
- SqlHelper.Con.Close();
- }
- }
- return result;
- }
- /// <summary>
- /// 执行返回一条记录的泛型对象
- /// </summary>
- /// <typeparam name="T">泛型类型</typeparam>
- /// <param name="reader">只进只读对象</param>
- /// <returns>泛型对象</returns>
- private static T ExecuteDataReader<T>(IDataReader reader)
- {
- T obj = default(T);
- try
- {
- Type type = typeof(T);
- obj = (T)Activator.CreateInstance(type);//从当前程序集里面通过反射的方式创建指定类型的对象
- //obj = (T)Assembly.Load(SqlHelper._assemblyName).CreateInstance(SqlHelper._assemblyName + "." + type.Name);//从另一个程序集里面通过反射的方式创建指定类型的对象
- PropertyInfo[] propertyInfos = type.GetProperties();//获取指定类型里面的所有属性
- foreach (PropertyInfo propertyInfo in propertyInfos)
- {
- for (int i = 0; i < reader.FieldCount; i++)
- {
- string fieldName = reader.GetName(i);
- if (fieldName.ToLower() == propertyInfo.Name.ToLower())
- {
- object val = reader[propertyInfo.Name];//读取表中某一条记录里面的某一列
- if (val != null && val != DBNull.Value)
- {
- Type valType = val.GetType();
- if (valType == typeof(float) || valType == typeof(double) || valType== typeof(decimal))
- {
- propertyInfo.SetValue(obj, Convert.ToDouble(val), null);
- }
- else if (valType == typeof(int))
- {
- propertyInfo.SetValue(obj, Convert.ToInt32(val), null);
- }
- else if (valType == typeof(DateTime))
- {
- propertyInfo.SetValue(obj, Convert.ToDateTime(val), null);
- }
- else if (valType == typeof(string))
- {
- propertyInfo.SetValue(obj, Convert.ToString(val), null);
- }
- }
- break;
- }
- }
- }
- }
- catch
- {
- throw;
- }
- return obj;
- }
- /// <summary>
- /// 执行返回一条记录的泛型对象
- /// </summary>
- /// <typeparam name="T">泛型类型</typeparam>
- /// <param name="commandText">Oracle语句或存储过程名</param>
- /// <param name="commandType">Oracle命令类型</param>
- /// <param name="param">Oracle命令参数数组</param>
- /// <returns>实体对象</returns>
- public static T ExecuteEntity<T>(string commandText, CommandType commandType, params OracleParameter[] param)
- {
- T obj = default(T);
- try
- {
- using (OracleCommand cmd = new OracleCommand(commandText, SqlHelper.Con))
- {
- cmd.CommandType = commandType;
- cmd.Parameters.AddRange(param);
- SqlHelper.Con.Open();
- OracleDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
- while (reader.Read())
- {
- obj = SqlHelper.ExecuteDataReader<T>(reader);
- }
- }
- }
- finally
- {
- if (SqlHelper.Con.State != ConnectionState.Closed)
- {
- SqlHelper.Con.Close();
- }
- }
- return obj;
- }
- /// <summary>
- /// 执行返回多条记录的泛型集合对象
- /// </summary>
- /// <typeparam name="T">泛型类型</typeparam>
- /// <param name="commandText">Oracle语句或存储过程名</param>
- /// <param name="commandType">Oracle命令类型</param>
- /// <param name="param">Oracle命令参数数组</param>
- /// <returns>泛型集合对象</returns>
- public static List<T> ExecuteList<T>(string commandText, CommandType commandType, params OracleParameter[] param)
- {
- List<T> list = new List<T>();
- try
- {
- using (OracleCommand cmd = new OracleCommand(commandText, SqlHelper.Con))
- {
- try
- {
- cmd.CommandType = commandType;
- if (param != null)
- {
- cmd.Parameters.AddRange(param);
- }
- SqlHelper.Con.Open();
- OracleDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
- while (reader.Read())
- {
- T obj = SqlHelper.ExecuteDataReader<T>(reader);
- list.Add(obj);
- }
- }
- catch (Exception ex)
- {
- list = null;
- }
- }
- }
- finally
- {
- if (SqlHelper.Con.State != ConnectionState.Closed)
- {
- SqlHelper.Con.Close();
- }
- }
- return list;
- }
- #endregion
- }
- }
C# 调用 Oracle的更多相关文章
- 电脑上不安装Oracle时,C# 调用oracle数据库,Oracle客户工具
Oracle的安装包通常都比较大,安装又比较费时,而且如果安装过程中不幸出错,各种蛋疼,即便是安装过N遍的老手,有时候安装起来也觉得挺烦.而工作中,通常服务器上面安装oracle就可以了,我们本地电脑 ...
- MyBatis调用Oracle存储过程
MyBatis调用Oracle存储过程 1.无输入和输出参数的存储过程 2.带有输入和输出参数的存储过程 3.返回游标的存储过程 mybatis中的配置文件代码 <resultMap type= ...
- java下实现调用oracle的存储过程和函数
在Oracle下创建一个test的账户,然后 1.创建表:STOCK_PRICES --创建表格 CREATE TABLE STOCK_PRICES( RIC VARCHAR() PRIMARY KE ...
- oracle学习笔记1:windows下oracle数据库安装及.net调用oracle数据库
1.下载32位或64位oracle数据库并且安装,安装时可以选择安装数据库实例或者不安装,如果不安装的话之后可以用Database Configuration Assistant(DBCA) 通过向导 ...
- ibatis.net调用oracle存储过返回游标SYS_REFCURSOR结果集
最近在用ibatis.net框架和oracle 11g开发一套程序.其中有一个需求就是通过存储过程,查询指定条件的数据集. 但是在开发的过程中遇到了问题,问题如下: 1.如何通过ibatis.net执 ...
- Java调用Oracle存储Package
Oracle的包Package中可以有很多存储,可通过该包的总调入口在java中直接调用. //java调用oracle的package代码 public boolean cal() throws j ...
- java基础---->java调用oracle存储过程(转)
存储过程是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,经过第一次编译后再次调用不需要再次编译,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它.今天 ...
- FSharp 调用 Oracle.ManagedDataAccess.dll
FSharp 调用 Oracle.ManagedDataAccess.dll 1.Oracle.ManagedDataAccess.dll 的下载地址.好像如今必需要注冊才干下载. 即使是 64 位系 ...
- C#调用Oracle的存储过程时,连接字符串需要配置PLSQLRSet=1
C#调用Oracle的存储过程时, 如果有个SYS_REFCURSOR的Output参数存储时, web.config文件中的连接字符串需要配置PLSQLRSet=1, 否则可能会报这个错:参数个数或 ...
随机推荐
- BoneCP 升级遇到的问题
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [c ...
- 自定义view(一)
最近在学习自定义view 一遍看一别学顺便记录一下 1.View的测量-------->onMeasure() 首先,当我们要画一个图形的时候,必须知道三个数据:位置,长度,宽度 才能确定 ...
- Android开发学习之路-3DTouch效果模仿
3D Touch是什么效果的大家应该都知道了.什么?不知道,那也没办法呀,我也没有iPhone 6s演示给你看的. 本篇博客要做的效果图: 来个低质量动图: 这个动图效果不是很好,实际上模糊效果应该是 ...
- Golang 生成随机数
package main import ( "fmt" "math/rand" "time" ) func main() { rand.Se ...
- 从零开始编写自己的C#框架(14)——T4模板在逻辑层中的应用(三)
原本关于T4模板原想分5个章节详细解说的,不过因为最近比较忙,也不想将整个系列时间拉得太长,所以就将它们整合在一块了,可能会有很多细节没有讲到,希望大家自己对着代码与模板去研究. 本章代码量会比较大, ...
- T-SQL:毕业生出门需知系列(九)
<SQL 必知必会>读书笔记 -- 第9课 汇总数据 9.1 聚集函数:对某些行运行的函数,计算并返回一个值 案例: -- 确定表中函数 -- 获得表中某些行的和 -- 找出表列的最大值. ...
- ARM CPU大小端
ARM CPU大小端: 大端模式:低位字节存在高地址上,高位字节存在低地址上 小端模式:高位字节存在高地址上,低位字节存在低地址上 STM32属于小端模式,简单的说,比如u32 temp=0X1234 ...
- Linux A机器免密码SSH登录B机器
一.问题 如上,A机器经常需远程操作B机器,传输文件到B机器,每次输入帐号密码过于繁琐,下文通过ssh公钥能解免密码操作问题. 二.解决 1.方案 SSH认证采用公钥与私钥认证方式. 2.步骤 1) ...
- python 数据类型---列表使用 之二 (增删改查)
列表的操作 1.列表的修改 >>> name ['Frank', 'Lee', 2, ['Andy', 'Troy']] >>> name[0] = "F ...
- 多线程并发同一个表问题(li)
现有数据库开发过程中对事务的控制.事务锁.行锁.表锁的发现缺乏必要的方法和手段,通过以下手段可以丰富我们处理开发过程中处理锁问题的方法.For Update和For Update of使用户能够锁定指 ...