一. 前情提要

一般.NET环境连接Oracle数据库,是通过 TNS/SQL.NET 配置文件,而 TNS 必须要 Oracle 客户端(如果连接的是服务器的数据库,本地还要装一个 client ,还要把 TNS 文件放进去安装路径里面)

1. Using System.Data.OracleClient

微软自带的,据说已经不维护了,总之是需要客户端的。

2. Oracle.DataAccess.dll

一般在 Oracle 安装目录下 product\11.2.0\dbhome_1\ODP.NET\bin\2.x 里面。但是我碰到的问题就是:

Oracle.DataAccess.Client.OracleException: The provider is not compatible with the version of Oracle client

无论是换 2.112.1 的Oracle.DataAccess.x86还是 4.112.3 的Oracle.DataAccess.x86.4,怎么都找不到原因。

没错,Oracle.DataAccess.dll是分32为和64位的,主要看你的客户端版本

3. Oracle.ManagedDataAccess.dll(极力推荐)

Oracle官网为C#提供的全新ODP.NET方式的全托管驱动,并且还支持EF,支持分布式事务。

NuGet搜索一下就能找到,ASP.NET Core 版的也是有。

这三个 dll 使用的方式我觉得是没有什么不同的(至少我还没接触到不同的地方)

但是这个 dll 的使用方法有些不同,后续讲到

二. 操作类

1. 获取连接字符串

  • 这里有个比较坑的地方。使用ConfigurationManager类的时候,读取的web.config/App.config都必须要在“调用”项目中存在,而不是在“被调用”中。

    通俗点:我新建了了一个Common的项目,用来存放一些公共的工具类(比如连接数据库、防注入、字符转换等),里面写一个OracleHelper类用来读取数据库。

    现在WebUI这个项目要调用到Common.OracleHelper里的方法,那么连接用的web.config/App.config就必须写在WebUI项目下,而不是Common
  1. // 1. 从 web.config 获取(必须是非静态类,不然会报错)
  2. private string connString = ConfigurationManager.ConnectionStrings["Conn_DB"].ToString();
  3. // 但是后面的操作要想直接使用,而不用 new 一个对象的话,就需要在这里建一个用于初始化的字段。
  4. private static OracleHelper _instance;
  5. public static OracleHelper Instance
  6. {
  7. get
  8. {
  9. if (_instance == null)
  10. _instance = new OracleHelper();
  11. return _instance;
  12. }
  13. }
  14. // 2. 直接写,不需要配置文件
  15. static string connString = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=118.31.20.98)(PORT=33602))(CONNECT_DATA=(SERVICE_NAME=STUTEST)));Persist Security Info=True;User ID=WMSTEST;Password=WMSTEST;";
  16. // 还有就是 ASP.NET Core 的注入构造函数,这个在文章最后

2. 查询表数据

DataSet

  1. /// <summary>
  2. /// 查询表数据(单表)
  3. /// </summary>
  4. /// <param name="sql">sql语句</param>
  5. /// <returns></returns>
  6. public static DataSet SelectData(string sql)
  7. {
  8. DataSet ds = new DataSet();
  9. try
  10. {
  11. using (OracleConnection conn = new OracleConnection(Instance.connString))
  12. {
  13. OracleCommand cmd = new OracleCommand(sql, conn);
  14. OracleDataAdapter adapter = new OracleDataAdapter(cmd);
  15. adapter.Fill(ds);
  16. return ds;
  17. }
  18. }
  19. catch (Exception e)
  20. {
  21. Console.Write(e);
  22. }
  23. return null;
  24. }

DataTable

  1. /// <summary>
  2. /// 查询表数据(单表)
  3. /// </summary>
  4. /// <param name="sql">sql语句</param>
  5. /// <returns></returns>
  6. public static DataTable SelectData(string sql)
  7. {
  8. DataTable dt = new DataTable();
  9. try
  10. {
  11. using (OracleConnection conn = new OracleConnection(Instance.connString))
  12. {
  13. OracleCommand cmd = new OracleCommand(sql, conn);
  14. OracleDataAdapter adapter = new OracleDataAdapter(cmd);
  15. adapter.Fill(dt);
  16. return dt;
  17. }
  18. }
  19. catch (Exception e)
  20. {
  21. Console.Write(e);
  22. }
  23. return null;
  24. }

DataView

  1. /// <summary>
  2. /// 查询表数据(单表)
  3. /// </summary>
  4. /// <param name="sql">sql语句</param>
  5. /// <returns></returns>
  6. public static DataView SelectData(string sql)
  7. {
  8. DataTable dt = new DataTable();
  9. try
  10. {
  11. using (OracleConnection conn = new OracleConnection(Instance.connString))
  12. {
  13. OracleCommand cmd = new OracleCommand(sql, conn);
  14. OracleDataAdapter adapter = new OracleDataAdapter(cmd);
  15. adapter.Fill(dt);
  16. return dt.DefaultView;
  17. }
  18. }
  19. catch (Exception e)
  20. {
  21. Console.Write(e);
  22. }
  23. return null;
  24. }

3. 增/删/改

插入,删除,修改都可用一个方法,执行语句相同,返回true则表示有数据收到影响

  1. /// <summary>
  2. /// 执行sql 语句
  3. /// </summary>
  4. /// <param name="sql"></param>
  5. /// <returns>返回影响的行数</returns>
  6. public static Boolean AddUpDelData(string sql)
  7. {
  8. try
  9. {
  10. using (OracleConnection conn = new OracleConnection(Instance.connString))
  11. {
  12. conn.Open();
  13. OracleCommand cmd = new OracleCommand(sql, conn);
  14. int row = cmd.ExecuteNonQuery();
  15. conn.Close();
  16. if (row > 0)
  17. {
  18. return true;
  19. }
  20. }
  21. }
  22. catch (Exception e)
  23. {
  24. Console.Write(e);
  25. }
  26. return false;
  27. }

4. 批量 增/删/改(事务)

事务,事务是多条SQL语句一起执行,如果一条错误,那么将会回滚。这个在表之间主外键关系是有必要同时生效。只要把SQL语句放在List集合中,传到方法中即可

  1. /// <summary>
  2. /// 执行sql List语句
  3. /// </summary>
  4. /// <param name="sqlText">需要执行的List</param>
  5. /// <returns>返回true/false</returns>
  6. public static Boolean ExeTransaction(List<string> sqlText)
  7. {
  8. using (OracleConnection conn = new OracleConnection(Instance.connString))
  9. {
  10. conn.Open();
  11. OracleTransaction tran = conn.BeginTransaction();
  12. try
  13. {
  14. OracleCommand cmd = new OracleCommand();
  15. cmd.Transaction = tran;
  16. cmd.Connection = conn;
  17. foreach(string item in sqlText)
  18. {
  19. cmd.CommandText = item;
  20. cmd.ExecuteNonQuery();
  21. }
  22. tran.Commit();
  23. return true;
  24. }
  25. catch (Exception et)
  26. {
  27. tran.Rollback();
  28. return false;
  29. }
  30. finally
  31. {
  32. conn.Close();
  33. }
  34. }
  35. }

三. 配置项(这里我使用的是 Oracle.ManagedDataAccess.dll)

1. ASP.NET MVC

web.config

  1. <connectionStrings>
  2. <add name="Conn_DB" connectionString="Data Source=(DESCRIPTION =(ADDRESS_LIST =(ADDRESS =
  3. (PROTOCOL = TCP)(HOST = 192.168.1.13)(PORT=8686)))(CONNECT_DATA =(SERVER = DEDICATED)
  4. (SERVICE_NAME = STUTEST)));User Id=WMSTEST;Password=WMSTEST;" providerName="Oracle.DataAccess.Client" />
  5. </connectionStrings>

下面分几种情况:

1) 无配置文件,直接连接DB

无SQL*Net 配置文件tnsnames.ora

  1. string conString = "User Id=hr; password=hr;Data Source=localhost:1521/orcl; Pooling=false;";

2) 使用配置文件方式

使用tnsnames.ora文件,此放置在应用程序同目录,至于代码中怎么引用 同目录下的 TNS 我也没尝试过。tnsnames.ora内容:

  1. ORCL =
  2. (DESCRIPTION =
  3. (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
  4. (CONNECT_DATA =
  5. (SERVER = DEDICATED)
  6. (SERVICE_NAME = orcl)
  7. )
  8. )

使用web.config/App.config配置文件定义别名(无tnsnames.ora文件)

  1. <oracle.manageddataaccess.client>
  2. <version number="*">
  3. <dataSources>
  4. <dataSource alias="orcl" descriptor="(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME = orcl)))"/>
  5. </dataSources>
  6. </version>
  7. </oracle.manageddataaccess.client>

使用TNS_ADMIN目录:

  1. <oracle.manageddataaccess.client>
  2. <version number="*">
  3. <settings>
  4. <setting name="TNS_ADMIN" value="C:\app\oracle\product\12.1.0\client_1\Network\Admin\"/>
  5. </settings>
  6. </version>
  7. </oracle.manageddataaccess.client>

2. ASP.NET Core,我这边使用 Mongodb演示

appsetting.json


  1. "MongodbHost": {
  2. "Connection": "mongodb://127.0.0.1:27017",
  3. "DataBase": "Blog_Server",
  4. "Table": ""
  5. }

MongodbHostOptions.cs既然是面向对象的语言,最好是定义一个实体类

  1. public class MongodbHostOptions
  2. {
  3. /// <summary>
  4. /// 连接字符串
  5. /// </summary>
  6. public string Connection { get; set; }
  7. /// <summary>
  8. /// 库
  9. /// </summary>
  10. public string DataBase { get; set; }
  11. /// <summary>
  12. /// 表
  13. /// </summary>
  14. public string Table { get; set; }
  15. }

Startup.cs

  1. // 首先 using 一下命名空间
  2. using Microsoft.Extensions.Configuration;
  3. // 后面的就是在 Startup 中的配置
  4. ...
  5. public Startup(IConfiguration configuration)
  6. {
  7. Configuration = configuration;
  8. }
  9. public IConfiguration Configuration { get; }
  10. public void ConfigureServices(IServiceCollection services)
  11. {
  12. services.AddControllers();
  13. // MongodbHost信息 依赖注入一下,这样就可以在别的 类 的构造函数中注入
  14. services.Configure<MongodbHostOptions>(Configuration.GetSection("MongodbHost"));
  15. }
  16. ...

注入示例

  1. // MongodbHost信息,类对象之下
  2. private readonly MongodbHostOptions _mongodbHostOptions;
  3. // 构造函数,注入一下
  4. public BlogController(IOptions<MongodbHostOptions> mongodbHostOptions)
  5. {
  6. _mongodbHostOptions = mongodbHostOptions.Value;
  7. }

四. 完整工具类

  1. using Oracle.ManagedDataAccess.Client;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Configuration;
  5. using System.Data;
  6. using System.Reflection;
  7. namespace OracleHelper
  8. {
  9. public class OracleHelper
  10. {
  11. // 从 web.config 获取
  12. private string connString = ConfigurationManager.ConnectionStrings["Conn_DB"].ToString();
  13. private static OracleHelper _instance;
  14. public static OracleHelper Instance
  15. {
  16. get
  17. {
  18. if (_instance == null)
  19. _instance = new OracleHelper();
  20. return _instance;
  21. }
  22. }
  23. /// <summary>
  24. /// 查询表数据(单表)
  25. /// </summary>
  26. /// <param name="sql">sql语句</param>
  27. /// <returns></returns>
  28. public static object GetData(string sql, int type)
  29. {
  30. try
  31. {
  32. using (OracleConnection conn = new OracleConnection(Instance.connString))
  33. {
  34. OracleCommand cmd = new OracleCommand(sql, conn);
  35. OracleDataAdapter adapter = new OracleDataAdapter(cmd);
  36. DataSet ds = new DataSet();
  37. adapter.Fill(ds);
  38. return ds;
  39. }
  40. }
  41. catch (Exception ex)
  42. {
  43. throw ex;
  44. }
  45. }
  46. /// <summary>
  47. /// 执行sql 语句
  48. /// </summary>
  49. /// <param name="sql"></param>
  50. /// <returns>返回影响的行数</returns>
  51. public static int ExecuteNonQuery(string sql)
  52. {
  53. try
  54. {
  55. using (OracleConnection conn = new OracleConnection(Instance.connString))
  56. {
  57. conn.Open();
  58. OracleCommand cmd = new OracleCommand(sql, conn);
  59. int row = cmd.ExecuteNonQuery();
  60. conn.Close();
  61. if (row > 0)
  62. {
  63. return row;
  64. }
  65. }
  66. }
  67. catch (Exception e)
  68. {
  69. Console.Write(e);
  70. }
  71. return 0;
  72. }
  73. /// <summary>
  74. /// 执行sql List语句
  75. /// </summary>
  76. /// <param name="sqlText">需要执行的List</param>
  77. /// <returns>返回true/false</returns>
  78. public static bool ExeTransaction(List<string> sqlText)
  79. {
  80. using (OracleConnection conn = new OracleConnection(Instance.connString))
  81. {
  82. conn.Open();
  83. OracleTransaction tran = conn.BeginTransaction();
  84. try
  85. {
  86. OracleCommand cmd = new OracleCommand();
  87. cmd.Transaction = tran;
  88. cmd.Connection = conn;
  89. foreach (string item in sqlText)
  90. {
  91. cmd.CommandText = item;
  92. cmd.ExecuteNonQuery();
  93. }
  94. tran.Commit();
  95. return true;
  96. }
  97. catch (Exception ex)
  98. {
  99. tran.Rollback();
  100. throw ex;
  101. }
  102. finally
  103. {
  104. conn.Close();
  105. }
  106. }
  107. }
  108. }
  109. }

五. 控制台输出

  1. //多表多行多列的情况
  2. foreach (DataTable dt in YourDataset.Tables) //遍历所有的datatable
  3. {
  4. foreach (DataRow dr in dt.Rows) ///遍历所有的行
  5. foreach (DataColumn dc in dt.Columns) //遍历所有的列
  6. Console.WriteLine("{0}, {1}, {2}", dt.TableName, dc.ColumnName, dr[dc]); //表名,列名,单元格数据
  7. }
  8. //遍历一个表多行多列
  9. foreach (DataRow mDr in dataSet.Tables[0].Rows)
  10. {
  11. foreach (DataColumn mDc in dataSet.Tables[0].Columns)
  12. {
  13. Console.WriteLine(mDr[mDc].ToString());
  14. }
  15. }
  16. //遍历一个表多行一列
  17. foreach (DataRow row in DataSet1.Tables[0].Rows)
  18. {
  19. Console.WriteLine(row[0].ToString());
  20. }
  21. //一行一列
  22. ds.Tables[0].Rows[0]["字段"];

本文参考以下两位大佬,感谢:

springsnow:https://www.cnblogs.com/springsnow/p/11393678.html

withJoy:https://www.cnblogs.com/xqz0618/p/Oracle.html

C# 连接 Oracle数据库增删改查,事务的更多相关文章

  1. ASP.NET C# 连接 Oracle数据库增删改查,事务

    一.知识介绍 ①ASP.NET 使用的是MVC模式,开发工具Visual studio ,语言C# ②Oracle是比较重型的数据库,这里主要介绍连接数据库,对数据进行具体的使用 ③Visual St ...

  2. Java连接MySQL数据库增删改查通用方法

    版权声明:本文为博主原创文章,未经博主允许不得转载. Java连接MySQL数据库增删改查通用方法 运行环境:eclipse+MySQL 以前我们Java连接MySQL数据库都是一个数据库写一个类,类 ...

  3. jsp-2 简单的servlet连接mysql数据库 增删改查

    连接mysql数据库的操作 有增删改查 用的包有 commons-lang3-3.5 mysql-connector-java-5.1.40-bin 但是实际上也就是 数据查询和数据处理两种 所以对数 ...

  4. Mybatis连接Oracle实现增删改查实践

    1. 首先要在项目中增加Mybatis和Oracle的Jar文件 这里我使用的版本为ojdbc7 Mybatis版本为:3.2.4 2. 在Oracle中创建User表 create table T_ ...

  5. 【转】mybatis连接Oracle做增删改查

    原文地址:http://blog.csdn.net/liumengcheng/article/details/34422475 入门请看http://blog.csdn.NET/liumengchen ...

  6. java 连接oracle 进行增删改查

    1.在DAO层新增类OraclePersionDao package com.test.dao; import java.sql.*; /** * Created by wdw on 2017/9/1 ...

  7. java连接mysql数据库增删改查操作记录

    1. 连接数据库.得到数据库连接变量 注意连接数据库的时候 (1)打开DB Browser 新建一个Database Driver,注意加入Driver JARs的时候加入的包,我的是mysql-co ...

  8. Python cx_oracle自动化操作oracle数据库增删改查封装,优化返回查询数据

    # coding=utf-8 import cx_Oracle import os import json os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_C ...

  9. python2.7入门---操作mysql数据库增删改查

    Python 标准数据库接口为 Python DB-API,Python DB-API为开发人员提供了数据库应用编程接口.Python 数据库接口支持非常多的数据库,你可以选择适合你项目的数据库: G ...

随机推荐

  1. Oracle 表空间扩容

    1 系统表空间扩容 注:表空间监测或扩容方式很多,这里只提供一种方便使用的方法 1)查询SQL 注:需要输入百分比,如:90,就可查出使用率超过90%的表空间, with t as (select b ...

  2. StringJoiner 源码阅读

    StringJoiner 属性说明 /** * StringJoiner 使用指定的分割符将多个字符串进行拼接,并可指定前缀和后缀 * * @see java.util.stream.Collecto ...

  3. DBCP连接池参数解释

    1.<!-- 数据源1 --> 2. <bean id="dataSource" 3. class="org.apache.commons.dbcp.B ...

  4. CSS操作表格的边框和表格的属性示例代码

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. 判断是否为日期格式 与 判断是否为BigDecimal

    import java.text.ParseException;import java.text.SimpleDateFormat; /** * * 说明:判断是否为日期格式 * @param str ...

  6. jq 实时监听input输入框的变化

    项目需求中有时候需要实时监测 input 的值变化,虽然 input 自身有 focus 和 blur 事件,但是有时候跟需求不符合. 所以实时监听 input 值变化的代码为: $("#i ...

  7. OnCustomDraw

    ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CMyListCtrl::OnNMCustomdraw) ON_NOTIFY : Comes from a child co ...

  8. docker命令大全与资源汇总

    容器生命周期管理 run  //创建一个新的容器并运行一个命令 start/stop/restart  //启动一个或多个已经被停止的容器:停止一个运行中的容器:重启容器 kill  //杀掉一个运行 ...

  9. Typora快捷键记录

    目前使用的是Typora这款Markdown软件,记录一下快捷键用法: 1.无序列表,黑色实心圆点或白色空心圆点 首先去除缩进,使用“Ctrl”+"["键或者“Shift”+&qu ...

  10. 解析之Apache解析