源起

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

此处只做记录用 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. 吴裕雄 python 神经网络——TensorFlow 卷积神经网络水果图片识别

    #-*- coding:utf- -*- import time import keras import skimage import numpy as np import tensorflow as ...

  2. VSAN磁盘扩容与收缩(二)

  3. Android开发之《安全防护》

    逆向 java混淆 so加固 网络传输安全

  4. MongoDBcrud操作,采集部分代码

    using System; using System.Collections.Generic; using System.ComponentModel.Design; using System.Lin ...

  5. JDK1.8新特性Lambda表达式

    /** * Lambda * @date 2019/8/2 10:03 */ public class Lamda { public static void main(String[] args){ ...

  6. IOS常见语法解惑

    由于工作过程中经常需要查看IOS的Objective-C代码,遂把一些常见的.有疑问的OC语法列出,方便之后会看,提升效率. Objective-C中的@语法 @interface告诉编译器,我要声明 ...

  7. Selenium的Web自动化测试(送源码)

    8.1  Selenium自动化测试准备 1.Selenium介绍 Selenium是一个Web开源自动化测试框架,页面级操作,模拟用户真实操作,API从系统层面触发事件. Selenium 1.0  ...

  8. Seata-一站式分布式事务解决方案

    Fescar 2019 年 1 月,阿里巴巴中间件团队发起了开源项目 Fescar(Fast & EaSy Commit And Rollback),和社区一起共建开源分布式事务解决方案. F ...

  9. 安卓权威编程指南 挑战练习(第26章 在 Lollipop 设备上使用 JobService)

    26.11 挑战练习:在 Lollipop 设备上使用 JobService 请创建另一个 PollService 实现版本.新的 PollService 应该继承 JobService 并使用 Jo ...

  10. 移动端使用mint-ui组件loadmore填坑

      链接地址为 https://mint-ui.github.io/docs/#/en2/loadmore ,这里需要注意引入的方式,我这里是用cdn的方式引入的.请结合官方API阅读本文章. 2.在 ...