源起

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

此处只做记录用 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. 关于AI行业创业的6个问题

    第一个问题:互联网 vs 人工智能 首先如果今天大家选择创业,我建议更应该关注人工智能,而非互联网.为什么这么讲? 1. 互联网的流量红利已经消失: 以PC来说,全球PC出货量连续5年下滑.大家知道国 ...

  2. motionbuilder卸载/完美解决安装失败/如何彻底卸载清除干净motionbuilder各种残留注册表和文件的方法

    在卸载motionbuilder重装motionbuilder时发现安装失败,提示是已安装motionbuilder或安装失败.这是因为上一次卸载motionbuilder没有清理干净,系统会误认为已 ...

  3. SSM 生成mapper中xml文件:未能解析映射资源:“文件嵌套异常

    错误日记我就网上随便找个贴着: 错误一: org.springframework.beans.factory.BeanCreationException: Error creating bean wi ...

  4. VisualStudioCode通过SSH远程编辑文件

    翻译修改自:https://codepen.io/ginfuru/post/remote-editing-files-with-ssh 在远程服务器上编写文件是一件很糟糕的事情,vim和其他终端编辑器 ...

  5. Tuning xgboost in R:Part 1

    第一次调整Boosting算法的参数可能是一个非常艰难的任务.有很多参数可供选择,调整不同的参数会有不同的结果产生.最好的调参可能是取决于数据.每当我得到一个新的数据集,我都会学到一些新的东西.对分类 ...

  6. 分布式文件系统与HDFS

    HDFS,它是一个虚拟文件系统,用于存储文件,通过目录树来定位文件:其次,它是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色. HDFS 的设计适合一次写入,多次读出的场景,且不 ...

  7. vue子组件使用自定义事件向父组件传递数据

    使用v-on绑定自定义事件可以让子组件向父组件传递数据,用到了this.$emit(‘自定义的事件名称’,传递给父组件的数据) <!DOCTYPE html> <html lang= ...

  8. Apache JMeter--1基础介绍

    一.JMeter 介绍 近期公司要做jmeter调研,将性能测试推广到全部测试组,便一边学习一边做记录. Apache JMeter是100%纯JAVA桌面应用程序,是一款优秀的开源性能测试工具,被设 ...

  9. RE模块(正则)

    RE模块和正则表达式 正则表达式 正则就是用来筛选字符串中的特定的内容的(只要是reg...一般情况下都是跟正则有关) re模块与正则表达式之间的关系: 正则表达式不是python独有的 它是一门独立 ...

  10. webpack在用dev-server的时候怎么配置多入口文件

    类似下面这样就可以了,entry设置为对象 每个入口设置为属性,属性的值是一个数组,就可以像单入口一样往这个数组添加entry: { Profile: [ 'webpack-dev-server/cl ...