源起

在公司做项目时 经常出现 实体结构和线上的数据结构以及公司开发库数据结构不匹配的问题 但是又不能直接把开发库导入到生产库因为生产库已经有实际数据了 所以弄了一个小工具

此处只做记录用 demo级 未经过优化

依赖包

DapperExtensions.NetCore

Newtonsoft.Json

Oracle.ManagedDataAccess.Core

代码

新建一个名为 DBHelper 的 core 2.1 控制台程序 加入如下代码:(ps:实体类自备  本例中的实体类通过sqlsugar生成)

using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using CommonHelper;
using Dapper;
using DapperExtensions;
using Newtonsoft.Json; namespace DBHelper
{
class Program
{
//实体模型路径
public static string modelpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DAO");
//实际数据结构获取源
public const string sourcedbconnStr = "Data Source=192.168.200.151/orcl;User ID=BG;Password=1;";
//要比较的数据库连接串
public const string todbconnStr = "Data Source=192.168.200.151/orcl;User ID=BG2019;Password=1;";
//缓存数据结构对象 如果存在 则不再去sourcedb中获取结构
public static string SaveFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "sourceList.txt");
//生成的添加字段语句
public static string SqlSaveFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "sql.txt");
public static List<string> GetAllTableName()
{
DirectoryInfo di = new DirectoryInfo(modelpath);
var res =new List<string>();
foreach (var item in di.GetFiles("*.cs"))
{
if (!item.Name.ToLower().StartsWith("base"))
res.Add(item.Name.Replace(item.Extension,""));
}
return res;
} static void Main(string[] args)
{
//记录所有的源数据库 数据结构
List<SourceSaveList> sl = new List<SourceSaveList>();
var tableNames = GetAllTableName();
if (File.Exists(SaveFilePath))
{
using (FileStream fs = new FileStream(SaveFilePath, FileMode.Open))
{
using (StreamReader sw = new StreamReader(fs))
{
var ss = sw.ReadToEnd();
sl = JsonConvert.DeserializeObject<List<SourceSaveList>>(ss);
}
}
}
else
{
var sourceDB = new DapperHelper(sourcedbconnStr);
foreach (var item in tableNames)
{
var source =sourceDB.Conn.Query<TableColumns>(
$"select column_name,data_type,data_length from user_tab_cols where table_name='{item}'")
.ToList();
sl.Add(new SourceSaveList() { cols = source, tableName = item });
}
}
var toDB = new DapperHelper(todbconnStr);
StringBuilder sb = new StringBuilder();
foreach (var item in tableNames)
{
var source = sl.First(c => c.tableName == item).cols;
var to=
toDB.Conn.Query<TableColumns>($"select column_name,data_type,data_length from user_tab_cols where table_name='{item}'")
.ToList();
if (source.Count == to.Count) continue;
foreach (var source_column in source)
{
if (to.Any(c => c.COLUMN_NAME == source_column.COLUMN_NAME)) continue;
switch (source_column.DATA_TYPE)
{ case "DATE":
sb.Append($"alter table {item} add {source_column.COLUMN_NAME} DATE;");
break;
case "TIMESTAMP(6)":
sb.Append($"alter table {item} add {source_column.COLUMN_NAME} TIMESTAMP(6);");
break;
case "TIMESTAMP":
sb.Append($"alter table {item} add {source_column.COLUMN_NAME} TIMESTAMP({source_column.DATA_LENGTH});");
break;
default:
sb.Append($"alter table {item} add {source_column.COLUMN_NAME} {source_column.DATA_TYPE}({source_column.DATA_LENGTH});");
break;
}
sb.Append("\r\n");
}
} using (FileStream fs = new FileStream(SaveFilePath, FileMode.Create))
{
using (StreamWriter sw = new StreamWriter(fs))
{
sw.WriteLine(JsonConvert.SerializeObject(sl));
}
}
using (FileStream fs = new FileStream(SqlSaveFilePath, FileMode.Create))
{
using (StreamWriter sw = new StreamWriter(fs))
{
sw.WriteLine(sb.ToString());
}
} }
}
}

Program.cs

using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Dapper;
using DapperExtensions;
using DapperExtensions.Mapper;
using DapperExtensions.Sql;
using Oracle.ManagedDataAccess.Client; namespace CommonHelper
{
/// <summary>
/// dapper 帮助类
/// </summary>
public class DapperHelper
{
private Database Connection = null;
public DapperHelper(string conn)
{
var orcalConn = new OracleConnection(conn);
var orcaleconfig = new DapperExtensionsConfiguration(typeof(AutoClassMapper<>), new List<Assembly>(), new OracleDialect());
var orcaleGenerator = new SqlGeneratorImpl(orcaleconfig);
Connection = new Database(orcalConn, orcaleGenerator);
}
public IDbConnection Conn
{
get
{
return Connection.Connection;
}
} }
}

CommonHelper.cs

using System;
using System.Collections.Generic;
using System.Text; namespace DBHelper
{
public class SourceSaveList
{
public string tableName { get; set; }
public List<TableColumns> cols { get; set; }
}
}

SourceSaveList.cs

using System;
using System.Collections.Generic;
using System.Text; namespace DBHelper
{
public class TableColumns
{
public string COLUMN_NAME { get; set; }
public string DATA_TYPE { get; set; }
public string DATA_LENGTH { get; set; }
}
}

TableColumns

说明

1.根据本例子的配置 在bin 目录中 新建DAO目录并将具体的模型拷入

2.将代码中的sourcedbconnStr 改为开发库连接串

2.将代码中的todbconnStr 改为需要生产库连接串

3.运行后会生成 sourceList.txt 用来保存开发库数据结构 用来支持程序结构拷贝到网络无法连接的生产数据库中

如果该文件存在 则不会再去获取开发库数据结构

4.sql.txt 该文件即为缺失字段的添加语句  如果不存在该表 目前会将所有字段均生成添加语句 此情况目前需要手工处理

Oracle根据实体类比对2个数据库结构差异(demo)的更多相关文章

  1. 【oracle】Enterprise Manager 无法连接到数据库实例。下面列出了组件的状态---个人解决方案

    最近在学习Oracle,平常喜欢使用EM查看数据库状态,但是在最近突然发现EM连接不上Oracle数据库了,不知道问题出在哪里,只好卸载了重装.但是,在使用了几天以后,又出现了相同的问题,于是下决心将 ...

  2. oracle 实例名和服务名以及数据库名区别

    一.数据库名什么是数据库名?数据库名就是一个数据库的标识,就像人的身份证号一样.他用参数DB_NAME表示,如果一台机器上装了多全数据库,那么每一个数据库都有一个数据库名.在数据库安装或创建完成之后, ...

  3. oracle所在磁盘空间不足导致了数据库异常

    oracle所在磁盘空间不足导致了数据库异常.需要减小数据文件的大小来解决. 1.检查数据文件的名称和编号 select file#,name from v$datafile; 2.看哪个数据文件所占 ...

  4. EF Core中,通过实体类向SQL Server数据库表中插入数据后,实体对象是如何得到数据库表中的默认值的

    我们使用EF Core的实体类向SQL Server数据库表中插入数据后,如果数据库表中有自增列或默认值列,那么EF Core的实体对象也会返回插入到数据库表中的默认值. 下面我们通过例子来展示,EF ...

  5. MyBatis中使用实体中使用枚举,数据库中使用数值

    一.简介 本文主要讲MyBatis中使用实体中使用枚举,数据库中使用数值的解决方案.正常直接使用会报错,需要添加typeHandlers在mybatis-config.xml中. 二.解决方案 如下: ...

  6. Oracle、Db2、SqlServer、MySQL 数据库插入当前系统时间

    做易买网项目,由于对数据库插入系统时间不了解,常常遇到的问题: 1.java.sql.SQLException: ORA-01861: 文字与格式字符串不匹配.原因:由于获取系统时间类型不对,应为sy ...

  7. Mybatis中resultMap的作用-解决实体类属性名和数据库字段不一致

    解决实体类属性名和数据库字段不一致

  8. 使用jpa时,实体类有不存在数据库中的字段

    使用jpa时,实体类有不存在数据库中的字段.在改属性上面加上这个注解@Transient就可以解决问题.

  9. Oracle 11g静默安装软件+手工创建数据库

    由于是二次跳转+远程操作,无法使用图形界面,不能直接图形界面安装.采用静默安装软件+手工创建数据库的方式完成需求. 静默模式安装Oracle软件,配置监听程序 手工建库 检查各组件是否符合要求 1. ...

随机推荐

  1. 深入JVM内核--常用JVM配置参数

    Trace跟踪参数 -verbose:gc -XX:+printGC 可以打印GC的简要信息 [GC 4790K->374K(15872K), 0.0001606 secs] [GC 4790K ...

  2. [LC] 91. Decode Ways

    A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' - ...

  3. LG_3457_[POI2007]POW-The Flood

    题目描述 Description 你手头有一张该市的地图.这张地图是边长为 m∗n 的矩形,被划分为m∗n个1∗1的小正方形.对于每个小正方形,地图上已经标注了它的海拔高度以及它是否是该市的一个组成部 ...

  4. 使用 Commitizen 撰写 Angular 规范的 commit message

    本文为原创文章,转载请标明出处 目录 安装及配置 使用 1. 安装及配置 npm install -g commitizen npm install -g cz-conventional-change ...

  5. 使用JS-SDK自定义微信分享效果

    前言 刚进入一家新公司,接到的第一个任务就是需要需要自定义微信分享的效果(自定义缩略图,标题,摘要),一开始真是一脸懵逼,在网上搜索了半天之后大概有了方案.值得注意的是一开始搜索到的解决方案全是调用微 ...

  6. VBA 读取加密的Excel文件(VBA 加密Excel)

    实验成功的: ExcelApp.Workbooks.Open(文件路径,,,'密码') 这里很坑,搜了别人的博客,下面这个方法试了N次,都没用... ExcelApp.Workbooks.Open(文 ...

  7. java连接sqlserver数据简单操作

    首先我们下载微软的JDBC驱动包 https://www.microsoft.com/en-us/download/details.aspx?id=11774 下载好后我们打开如下图 点击Unzip ...

  8. 前端学习之路CSS基础学习一

    CSS CSS定义如何显示HTML元素,当浏览器读到一个样式表,它就按照这个样式表来对文档进行格式化. CSS实例 每个CSS样式由两个组成部分:选择器和声明.声明又包括包括属性和属性值.每个声明之后 ...

  9. rest-framework源码解析和自定义组件----版本

    版本 url中通过GET传参自定义的版本 12345678910111213141516171819202122 from django.http import HttpResponsefrom dj ...

  10. array-2

    数组的基本操作 JS随机操作数组元素 Math.random() 结果为0-1间的一个随机数[0,1) Math.round(num) 参数num为一个数值,函数结果为num四舍五入的整数 Math. ...