一. 前情提要

一般.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. 从 web.config 获取(必须是非静态类,不然会报错)
private string connString = ConfigurationManager.ConnectionStrings["Conn_DB"].ToString();
// 但是后面的操作要想直接使用,而不用 new 一个对象的话,就需要在这里建一个用于初始化的字段。
private static OracleHelper _instance; public static OracleHelper Instance
{
get
{
if (_instance == null)
_instance = new OracleHelper();
return _instance;
}
} // 2. 直接写,不需要配置文件
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;"; // 还有就是 ASP.NET Core 的注入构造函数,这个在文章最后

2. 查询表数据

DataSet

/// <summary>
/// 查询表数据(单表)
/// </summary>
/// <param name="sql">sql语句</param>
/// <returns></returns>
public static DataSet SelectData(string sql)
{
DataSet ds = new DataSet();
try
{
using (OracleConnection conn = new OracleConnection(Instance.connString))
{
OracleCommand cmd = new OracleCommand(sql, conn);
OracleDataAdapter adapter = new OracleDataAdapter(cmd);
adapter.Fill(ds);
return ds;
}
}
catch (Exception e)
{
Console.Write(e);
}
return null;
}

DataTable

/// <summary>
/// 查询表数据(单表)
/// </summary>
/// <param name="sql">sql语句</param>
/// <returns></returns>
public static DataTable SelectData(string sql)
{
DataTable dt = new DataTable();
try
{
using (OracleConnection conn = new OracleConnection(Instance.connString))
{
OracleCommand cmd = new OracleCommand(sql, conn);
OracleDataAdapter adapter = new OracleDataAdapter(cmd);
adapter.Fill(dt);
return dt;
}
}
catch (Exception e)
{
Console.Write(e);
}
return null;
}

DataView

/// <summary>
/// 查询表数据(单表)
/// </summary>
/// <param name="sql">sql语句</param>
/// <returns></returns>
public static DataView SelectData(string sql)
{
DataTable dt = new DataTable();
try
{
using (OracleConnection conn = new OracleConnection(Instance.connString))
{
OracleCommand cmd = new OracleCommand(sql, conn);
OracleDataAdapter adapter = new OracleDataAdapter(cmd);
adapter.Fill(dt);
return dt.DefaultView;
}
}
catch (Exception e)
{
Console.Write(e);
}
return null;
}

3. 增/删/改

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

/// <summary>
/// 执行sql 语句
/// </summary>
/// <param name="sql"></param>
/// <returns>返回影响的行数</returns>
public static Boolean AddUpDelData(string sql)
{
try
{
using (OracleConnection conn = new OracleConnection(Instance.connString))
{
conn.Open();
OracleCommand cmd = new OracleCommand(sql, conn);
int row = cmd.ExecuteNonQuery();
conn.Close();
if (row > 0)
{
return true;
}
}
}
catch (Exception e)
{
Console.Write(e);
}
return false;
}

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

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

/// <summary>
/// 执行sql List语句
/// </summary>
/// <param name="sqlText">需要执行的List</param>
/// <returns>返回true/false</returns>
public static Boolean ExeTransaction(List<string> sqlText)
{
using (OracleConnection conn = new OracleConnection(Instance.connString))
{
conn.Open();
OracleTransaction tran = conn.BeginTransaction();
try
{ OracleCommand cmd = new OracleCommand();
cmd.Transaction = tran;
cmd.Connection = conn;
foreach(string item in sqlText)
{
cmd.CommandText = item;
cmd.ExecuteNonQuery();
}
tran.Commit();
return true;
}
catch (Exception et)
{
tran.Rollback();
return false;
}
finally
{
conn.Close();
}
}
}

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

1. ASP.NET MVC

web.config

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

下面分几种情况:

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

无SQL*Net 配置文件tnsnames.ora

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

2) 使用配置文件方式

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

ORCL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl)
)
)

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

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

使用TNS_ADMIN目录:

<oracle.manageddataaccess.client>
<version number="*">
<settings>
<setting name="TNS_ADMIN" value="C:\app\oracle\product\12.1.0\client_1\Network\Admin\"/>
</settings>
</version>
</oracle.manageddataaccess.client>

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

appsetting.json


"MongodbHost": {
"Connection": "mongodb://127.0.0.1:27017",
"DataBase": "Blog_Server",
"Table": ""
}

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

public class MongodbHostOptions
{
/// <summary>
/// 连接字符串
/// </summary>
public string Connection { get; set; }
/// <summary>
/// 库
/// </summary>
public string DataBase { get; set; }
/// <summary>
/// 表
/// </summary>
public string Table { get; set; }
}

Startup.cs

// 首先 using 一下命名空间
using Microsoft.Extensions.Configuration; // 后面的就是在 Startup 中的配置
...
public Startup(IConfiguration configuration)
{
Configuration = configuration;
} public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
// MongodbHost信息 依赖注入一下,这样就可以在别的 类 的构造函数中注入
services.Configure<MongodbHostOptions>(Configuration.GetSection("MongodbHost")); }
...

注入示例

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

四. 完整工具类

using Oracle.ManagedDataAccess.Client;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Reflection; namespace OracleHelper
{
public class OracleHelper
{
// 从 web.config 获取
private string connString = ConfigurationManager.ConnectionStrings["Conn_DB"].ToString(); private static OracleHelper _instance; public static OracleHelper Instance
{
get
{
if (_instance == null)
_instance = new OracleHelper();
return _instance;
}
} /// <summary>
/// 查询表数据(单表)
/// </summary>
/// <param name="sql">sql语句</param>
/// <returns></returns>
public static object GetData(string sql, int type)
{
try
{
using (OracleConnection conn = new OracleConnection(Instance.connString))
{
OracleCommand cmd = new OracleCommand(sql, conn);
OracleDataAdapter adapter = new OracleDataAdapter(cmd);
DataSet ds = new DataSet();
adapter.Fill(ds);
return ds;
}
}
catch (Exception ex)
{
throw ex;
}
} /// <summary>
/// 执行sql 语句
/// </summary>
/// <param name="sql"></param>
/// <returns>返回影响的行数</returns>
public static int ExecuteNonQuery(string sql)
{
try
{
using (OracleConnection conn = new OracleConnection(Instance.connString))
{
conn.Open();
OracleCommand cmd = new OracleCommand(sql, conn);
int row = cmd.ExecuteNonQuery();
conn.Close();
if (row > 0)
{
return row;
}
}
}
catch (Exception e)
{
Console.Write(e);
}
return 0;
} /// <summary>
/// 执行sql List语句
/// </summary>
/// <param name="sqlText">需要执行的List</param>
/// <returns>返回true/false</returns>
public static bool ExeTransaction(List<string> sqlText)
{
using (OracleConnection conn = new OracleConnection(Instance.connString))
{
conn.Open();
OracleTransaction tran = conn.BeginTransaction();
try
{ OracleCommand cmd = new OracleCommand();
cmd.Transaction = tran;
cmd.Connection = conn;
foreach (string item in sqlText)
{
cmd.CommandText = item;
cmd.ExecuteNonQuery();
}
tran.Commit();
return true;
}
catch (Exception ex)
{
tran.Rollback();
throw ex;
}
finally
{
conn.Close();
}
}
} }
}

五. 控制台输出

//多表多行多列的情况
foreach (DataTable dt in YourDataset.Tables) //遍历所有的datatable
{
foreach (DataRow dr in dt.Rows) ///遍历所有的行
foreach (DataColumn dc in dt.Columns) //遍历所有的列
Console.WriteLine("{0}, {1}, {2}", dt.TableName, dc.ColumnName, dr[dc]); //表名,列名,单元格数据
}
//遍历一个表多行多列
foreach (DataRow mDr in dataSet.Tables[0].Rows)
{
foreach (DataColumn mDc in dataSet.Tables[0].Columns)
{
Console.WriteLine(mDr[mDc].ToString());
}
}
//遍历一个表多行一列
foreach (DataRow row in DataSet1.Tables[0].Rows)
{
Console.WriteLine(row[0].ToString());
}
//一行一列
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. springMVC中的ModelAndView说明

    ModelAndView 类别就如其名称所示,是代表了Spring Web MVC程式中呈现画面时所使用Model资料物件与View资料物件,由于Java程式中一次只能返回一个物件,所以ModelAn ...

  2. Function和Object 应该知道的

    javascript有5种基础的内建对象(Fundamental Objects),Object.Function.Error.Symbol.Boolean,而Object/Function尤为特殊, ...

  3. BeanFactory和ApplicationContext的区别+部分Spring的使用

    BeanFactory和ApplicationContext的区别 ApplicationContext 方式加载:创建容器的同时 容器初始化,容器所有的bean创建完毕   Spring容器中获取一 ...

  4. xftp上传文件到虚拟机linux失败问题

    如果想通过xftp上传文件到虚拟机linux时,可能会产生上传失败的问题 原因: 因为有些文件是只可读,所以要修改文件权限,可读可写,才可以上传成功. 解决方法: 第一种方法:用xftp连接虚拟机后, ...

  5. 20191114-4 Beta发布用户使用报告

    20191114-4 Beta发布用户使用报告 此作业要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/10007 组名:胜利点 组 ...

  6. 环信-(php)服务器端REST API

    <?php namespace Home\Controller; use Think\Controller; /** * 环信-服务器端REST API * @author limx <l ...

  7. jquery注册验证的写法

    在做注册页面时会用到jquery验证注册信息,用户名,密码,邮箱,手机号的验证,比较简单的,新手莫怪... <script> function Name(){ var name = $(& ...

  8. [Java]手动构建表达式二叉树,求值,求后序表达式

    Inlet类,这颗二叉树是”人力运维“的: package com.hy; public class Inlet { public static void main(String[] args) th ...

  9. T89379 【qbxt】复读警告

    T89379 [qbxt]复读警告 题解 这是一道DP题 设置状态  f[ i ][ j ]  前 i 个数中所选数字之和 % key 得 j 的最大方案数 当前我们该选择第 i 个数字了,那么这个数 ...

  10. Java-获取当前IP归属地

    知道IP,获取当前IP归属地的Java程序: package Main; import java.io.BufferedReader; import java.io.DataOutputStream; ...