当前位置: 首页 > news >正文

使用java备份和恢复SQLServer表数据

需求

近来工作中遇到一个问题,内网办公系统中的数据需要导出到外网中进行查询,外网的数据库中还有一些表存储外网的数据,因此无法使用全库备份恢复功能来满足需求。即只从内网数据库中导出若干表的内容至外网数据库的对应表。

其他解决方案:使用SQL Server自身的导出SQL语句的方法其实也可以,但是涉及到几十个表,一一手工导出工作量较大。

因此自己写了个函数,将内网中的表数据导出,根据数据生成insert into 语句,然后使用批处理的方式导入到外网数据库中。

1.表结构的分析

生成insert语句时,不得不面对的是引号的使用,对于int等类型无需引号,但是对于char、text等必须加上引号,一个表动辄几十个字段,人工用数组等方式记录字段的类型、名称再进行处理,也比较耗费精力,尤其是数据表的结构时常还在变化,而且是另一个开发公司在维护,何时变化也不得而知。这里通过分析建表语句完成了自动的字段类型的对应,从而大大减轻了人工维护字段及其类型的工作量。

譬如建表语句如下(在SQL Server企业管理器中选中表,Ctrl+C即可得到),这里存放一个文件中:

CREATE TABLE [Import_BizDescrs] ([DescrId] [char] (10) COLLATE Chinese_PRC_CI_AS NULL ,[DescrType] [char] (20) COLLATE Chinese_PRC_CI_AS NULL ,[DescrAt] [datetime] NULL ,[Descr] [text] COLLATE Chinese_PRC_CI_AS NULL ,[DescrBy] [char] (20) COLLATE Chinese_PRC_CI_AS NULL ,[BizId] [char] (10) COLLATE Chinese_PRC_CI_AS NULL ,[SampId] [char] (20) COLLATE Chinese_PRC_CI_AS NULL ,[AssistTaskId] [char] (20) COLLATE Chinese_PRC_CI_AS NULL ,[CreatePerson] [char] (20) COLLATE Chinese_PRC_CI_AS NULL ,[CreateDate] [datetime] NULL ,[UpdatePerson] [char] (20) COLLATE Chinese_PRC_CI_AS NULL ,[UpdateDate] [datetime] NULL 
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

从以上文字中,做出如下处理,即可获得表名、字段名、字段类型以及附带的是否需要引号。

public static void exportTableDataByCreateSQL(String createSQLFileName){ArrayList <String> fieldNames = new ArrayList<String>();ArrayList <String> fieldtypes = new ArrayList<String>();ArrayList <Boolean> needQuotationMark = new ArrayList<Boolean>();String tableName = "";String filePath = "C:\\importSQLs\\";String tmpString;try {BufferedReader reader = new BufferedReader(new FileReader(createSQLFileName));String line = reader.readLine();//从第一行获取表名			tableName = line.substring(line.indexOf("[")+1,line.indexOf("]"));;System.out.println(tableName) ;//后面获取其他信息while ((line = reader.readLine()) != null) {if(line.startsWith(")")){break;}tmpString = line.substring(line.indexOf("[")+1,line.indexOf("]"));fieldNames.add(tmpString);line = line.substring(line.indexOf("]")+1);tmpString = line.substring(line.indexOf("[")+1,line.indexOf("]"));fieldtypes.add(tmpString);	if(tmpString.contains("char")||tmpString.contains("text")||tmpString.contains("datetime")){needQuotationMark.add(true);}else{needQuotationMark.add(false);}}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}
}

2.备份表

获取到完整的字段、字段属性后,就可以开始生成SQL文件了,对于值为null的数据,略去相应的插入语句,同时由于是全表全量导入,开始时增加了delete from tableName;的语句

全部代码如下:

public static void exportTableDataByCreateSQL(String createSQLFileName){ArrayList <String> fieldNames = new ArrayList<String>();ArrayList <String> fieldtypes = new ArrayList<String>();ArrayList <Boolean> needQuotationMark = new ArrayList<Boolean>();String tableName = "";String filePath = "C:\\importSQLs\\";String tmpString;try {BufferedReader reader = new BufferedReader(new FileReader(createSQLFileName));			String line = reader.readLine();//从第一行获取表名			tableName = line.substring(line.indexOf("[")+1,line.indexOf("]"));;//后面获取其他信息while ((line = reader.readLine()) != null) {if(line.startsWith(")")){break;}tmpString = line.substring(line.indexOf("[")+1,line.indexOf("]"));fieldNames.add(tmpString);line = line.substring(line.indexOf("]")+1);tmpString = line.substring(line.indexOf("[")+1,line.indexOf("]"));fieldtypes.add(tmpString);	if(tmpString.contains("char")||tmpString.contains("text")||tmpString.contains("datetime")){needQuotationMark.add(true);}else{needQuotationMark.add(false);}}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}//开始生成insert语句Connection conn;try {Class.forName("net.sourceforge.jtds.jdbc.Driver");conn = DriverManager.getConnection(GlobalVar.ConnURL,GlobalVar.ConnUser,GlobalVar.ConnPWD);Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery("SELECT * FROM " + tableName);     FileWriter writer = new FileWriter(filePath + tableName+".lims2", false);BufferedWriter bufferedWriter = new BufferedWriter(writer);	    bufferedWriter.write("delete from "+tableName + ";");bufferedWriter.newLine();while (rs.next()) {String FieldsString="";String ValuesString="";for(int i=0; i< needQuotationMark.size();i++){tmpString = rs.getString(fieldNames.get(i));	        		if(tmpString != null){if(FieldsString.equals("")){FieldsString += fieldNames.get(i);ValuesString += (needQuotationMark.get(i)?"'":"")+ tmpString.trim() +(needQuotationMark.get(i)?"'":"");}else{FieldsString += "," + fieldNames.get(i);ValuesString += "," + (needQuotationMark.get(i)?"'":"")+ tmpString.trim() + (needQuotationMark.get(i)?"'":"");}}}bufferedWriter.write("insert into "+ tableName + "("+FieldsString+")  values("+ValuesString+");");bufferedWriter.newLine();}bufferedWriter.close();writer.close();rs.close();stmt.close();conn.close();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}         	}

调用以上函数时,只需将保存建表语句的sql文件位置作为参数即可,在本项目中,生成的sql文件以.lims2结尾。

3.还原表

由于生成的表数据文件较多,这里写了个批处理文件,将导出的表数据文件和该批处理文件一起拷贝到外网服务器中,运行批处理即完成了导入操作。以后准备写个上传的页面,省去了远程桌面的麻烦。批处理文件如下:

osql -S 127.0.0.1 -U 用户名 -P 密码 -d lims2 -i Import_table1.lims2 -o Rst_Import_table1.log
osql -S 127.0.0.1 -U 用户名 -P 密码 -d lims2 -i import_table2.lims2 -o Rst_import_table2.log
osql -S 127.0.0.1 -U 用户名 -P 密码 -d lims2 -i Import_table3.lims2 -o Rst_Import_table3.log
osql -S 127.0.0.1 -U 用户名 -P 密码 -d lims2 -i import_table4.lims2 -o Rst_import_table4.log
osql -S 127.0.0.1 -U 用户名 -P 密码 -d lims2 -i import_table5.lims2 -o Rst_import_table5.log
........

结语

此方法适用于同步部分表而不是整库的情况,尤其是两个数据库无法直接通信,需要手工同步的场景。

相关文章:

使用java备份和恢复SQLServer表数据

需求 近来工作中遇到一个问题&#xff0c;内网办公系统中的数据需要导出到外网中进行查询&#xff0c;外网的数据库中还有一些表存储外网的数据&#xff0c;因此无法使用全库备份恢复功能来满足需求。即只从内网数据库中导出若干表的内容至外网数据库的对应表。 其他解决方案…...

27 UVM queue

uvm_queue类构建一个动态队列&#xff0c;该队列将按需分配并通过引用传递。 uvm_queue类声明&#xff1a; class uvm_queue #( type T int ) extends uvm_object 1 uvm_queue class hierarchy 2 uvm_queue class Methods 3 UVM Queue Example 在下面的示例中&#xff0c;…...

聊聊自动化测试的分层实践

技术群里&#xff0c;有同学聊起了各自在实践自动化测试时遇到的各种问题&#xff0c;最典型的就是落地难度和投入产出比。毕竟在当前这个时间节点&#xff0c;单纯的技术实践如果不能带来实际可见的业务价值&#xff0c;确实很影响个人绩效和团队产出。 这篇文章&#xff0c;…...

LVS那点事

LVS 原理 IPVS LVS 的 IP 负载均衡技术是通过 IPVS 模块来实现的&#xff0c;IPVS 是 LVS 集群系统的核心软件&#xff0c;它的主要作用是&#xff1a;安装在 Director Server 上&#xff0c;同时在 Director Server 上虚拟出一个 IP 地址&#xff0c;用户必须通过这个虚拟的…...

2022-2023年度广东省职业院校学生专业技能大赛“软件测试”赛项接口测试训练题目

接口测试 新增接口脚本编写和执行测试,并执行脚本。 (1)商品单位添加接口描述如下: 接口功能:提供商品单位新增处理。 接口地址(根据实际系统IP及端口自行替换): http://XX.XX.XX.XX:XXXX/prod-api/manager/category/add。 请求方式:POST。 请求参数:...

[Python][LeetCode]28. 找出字符串中第一个匹配项的下标

给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;则返回 -1 。 示例 1&#xff1a; 输入&#xff1a;haystack &quo…...

Prometheus监控mysql

docker-compose.yml 创建mysql mkdir/data/mysql -pcat > /data/mysql/docker-compose.yml << EOF version: 3.1 services:db:image: mysql:8.0restart: alwayscontainer_name: mysqlenvironment:TZ: Asia/ShanghaiLANG: en_US.UTF-8MYSQL_ROOT_PASSWORD: 123456comm…...

骑砍战团MOD开发(30)-游戏大地图map.txt

骑砍1战团mod开发-大地图制作方法_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1rz4y1c7wH/ 一.骑砍游戏大地图 骑砍RTS视角游戏大地图 大地图静态模型(map.txt) 军团/城镇图标(module_parties.py). 骑砍大地图的战争迷雾和天气通过API进行管理和控制: # Weather-h…...

关于 bringup sensor 时,曝光时间异常的问题排查

1、问题背景 这两天在配置 sc223a 这颗 sensor 的驱动&#xff0c;按 datasheet 的要求配置 sensor 的曝光后&#xff0c;发现最大曝光时间增加了一倍&#xff0c; sensor setting 用的是30fps &#xff0c;理论上最大的绝对曝光时间应该是 33ms 才正确&#xff0c;但实际用 …...

linux用户态与内核态通过字符设备交互

linux用户态与内核态通过字符设备交互 简述 Linux设备分为三类&#xff0c;字符设备、块设备、网络接口设备。字符设备只能一个字节一个字节读取&#xff0c;常见外设基本都是字符设备。块设备一般用于存储设备&#xff0c;一块一块的读取。网络设备&#xff0c;Linux将对网络…...

如何高效查询文件:Linux 下的多种方法详解

如何高效查询文件&#xff1a;Linux 下的多种方法详解 在日常工作中&#xff0c;我们经常需要查找文件&#xff0c;无论是寻找特定的代码文件、配置文件还是其他文档。Linux 提供了多种强大的命令和工具&#xff0c;通过巧妙地使用管道符&#xff0c;我们可以将这些命令组合起来…...

记矩阵基础概念

转自up&#xff1a;Naruto_Qcsdn&#xff1a;三维空间几何变换矩阵 先贴个站里分享的基础概念。 learn form 肥猫同学VFX b站&#xff1a;会用transform就会用矩阵 移动 旋转 缩放 1.transofrm ——输出变化矩阵 可以移动transform查看变化去理解 位移 缩放 旋转 由此—…...

用html,js和layui写一个简单的点击打怪小游戏

介绍&#xff1a; 一个简单的打怪小游戏&#xff0c;点击开始游戏后&#xff0c;出现攻击按钮&#xff0c;击败怪物后可以选择继续下一关和结束游戏。 继续下一个怪兽的血量会增加5点&#xff0c;攻击按钮会随机变色。 效果图&#xff1a; html代码&#xff1a; <!DOCTYPE…...

[线代]不挂科猴博士

行列式的性质 行列式的计算及应用 矩阵的运算上(加减,相乘,取行列式) 矩阵的运算下(转置,逆,秩) 向量组与线性空间 解方程组...

扩散式过滤器 水泵角通除污器 0阻力过滤器直角过滤器工作原理

​ 1&#xff1a;扩散式除污器过滤器介绍 扩散除污器是一种在多个领域都有应用的设备&#xff0c;例如在泵站中用于拦截介质中的杂质&#xff0c;净化介质&#xff0c;保护管路&#xff0c;提高水泵效率&#xff0c;延长水泵寿命等。它还可以方便地进行变径处理&#xff0c;可以…...

MetalLB:本地Kubernetes集群的LoadBalancer负载均衡利器

背景 在本地集群进行测试时&#xff0c;我们常常面临一个棘手的问题&#xff1a;Service Type不支持LoadBalancer&#xff0c;而我们只能选择使用NodePort作为替代。这种情况下&#xff0c;我们通常会配置Service为NodePort&#xff0c;并使用externalIPs将流量导入Kubernetes…...

C++判定终端ip和目标ip是否在同一局域网内

程序如下&#xff1a;用于判断给定的终端 IP、子网掩码和目标 IP 是否在同一局域网内。请注意&#xff0c;这个程序假设 IP 地址是用整数表示的。 #include <iostream> #include <sstream> #include <vector> #include <bitset>// Function to check …...

深入解析 可空值类型

前言&#xff1a; 问&#xff1a;为什么会有可空值类型的诞生&#xff1f; 答&#xff1a;应对在某些特定场景中获取的信息可能是不完整的。 C# 1中的可空值类型 在C#1中没有对应的表示Null值的方法。当时普遍都是采用其他方式。第一种在数据缺失的情况下给其一个默认值。第…...

esp32idf使用thingscloud例程

对于不同的消息类型&#xff0c;API 如下&#xff1a; 消息类型 HTTP Method HTTP URL 设备上报属性 POST /device/v1//attributes 设备获取属性 GET /device/v1//attributes 设备上报事件 POST /device/v1//event/report 您只需要将以上的 HTTP URL 和接入点拼接即可获得最终…...

记一次应急响应练习(Linux)

记一次应急响应练习(Linux) Linux&#xff1a; 请提交攻击者的IP地址 答&#xff1a; 192.168.31.132 思路&#xff1a; 通过查看历史命令和开放的8080端口看到这台主机上运行的是Tomcat服务。并且在历史命令中看到了Tomcat的安装路径。那么就算是找到了日志的查看点了&#x…...

OpenClaw我的龙虾怎么识别不了图片

问题现象 图片发送给龙虾&#xff0c;要么一直说没收到图片&#xff0c;要么提示不支持&#xff0c;要么提示安装OCR工具&#xff0c;要么就是识别出来的完全牛头不对马嘴。 解决方案 这里面涉及三个因素&#xff1a; 模型是否支撑图片识别配置中的input是否配置了image聊天渠道…...

Hotkey Detective:解决Windows热键冲突的创新方法

Hotkey Detective&#xff1a;解决Windows热键冲突的创新方法 【免费下载链接】hotkey-detective A small program for investigating stolen hotkeys under Windows 8 项目地址: https://gitcode.com/gh_mirrors/ho/hotkey-detective 问题引入&#xff1a;当你的快捷键…...

QGIS属性表关联Excel实战:5步搞定空间数据分析(附避坑指南)

QGIS属性表与Excel高效关联&#xff1a;从数据匹配到空间分析的完整指南 1. 为什么需要关联Excel与QGIS属性表&#xff1f; 在日常空间分析工作中&#xff0c;我们经常遇到这样的场景&#xff1a;拥有完整的空间数据&#xff08;如行政区划边界&#xff09;&#xff0c;但关键分…...

Android逆向实战:用Frida Hook自己写的APK,让1+1=88(附完整代码)

Android逆向实战&#xff1a;用Frida Hook自己写的APK&#xff0c;让1188&#xff08;附完整代码&#xff09; 在移动安全领域&#xff0c;逆向工程一直是个充满挑战又极具魅力的方向。想象一下&#xff0c;你能否让一个简单的计算器应用突然改变行为&#xff0c;比如让11的结果…...

OS X Auditor部署最佳实践:从本地运行到分布式取证

OS X Auditor部署最佳实践&#xff1a;从本地运行到分布式取证 【免费下载链接】OSXAuditor OS X Auditor is a free Mac OS X computer forensics tool 项目地址: https://gitcode.com/gh_mirrors/os/OSXAuditor OS X Auditor是一款强大的免费macOS计算机取证工具&…...

WebRTC信令交换实战:从Socket.io到RTCPeerConnection的完整流程解析

1. WebRTC信令交换的核心逻辑 第一次接触WebRTC时&#xff0c;我被它"点对点直接通信"的特性吸引&#xff0c;但很快发现真正的难点在于如何让两个设备找到彼此——这就是信令交换要解决的问题。信令交换就像两个陌生人交换电话号码的过程&#xff0c;只不过这里交换…...

AI混音师登场:音频自动混音技术全景解读与实战展望

AI混音师登场&#xff1a;音频自动混音技术全景解读与实战展望 引言 在AIGC浪潮席卷内容创作的今天&#xff0c;音频制作领域正经历一场静默革命。从专业录音棚到手机直播间&#xff0c;“一键母带”、“智能平衡”功能已不再陌生。这背后&#xff0c;正是音频自动混音技术在驱…...

从一条SQL到HDFS文件:手把手拆解Hive在YARN上的完整‘跑路’流程

从一条SQL到HDFS文件&#xff1a;手把手拆解Hive在YARN上的完整执行链路 当你在Beeline客户端输入一条看似简单的HiveQL查询时&#xff0c;背后究竟发生了什么&#xff1f;这条SQL如何穿越层层组件&#xff0c;最终变成分布式文件系统上的数据块操作&#xff1f;本文将带你以系…...

Python内存修复不靠猜:用objgraph+gc.get_referrers+自定义Allocator实现可视化追踪(工业级方案)

第一章&#xff1a;Python内存修复不靠猜&#xff1a;用objgraphgc.get_referrers自定义Allocator实现可视化追踪&#xff08;工业级方案&#xff09;Python内存泄漏常表现为对象持续增长却无法被回收&#xff0c;传统日志与print调试效率低下。本章提供一套可落地的工业级诊断…...

GIL消失后的混沌现场:共享对象修改异常、原子性丢失、引用计数溢出,一文收全7种致命报错及防御代码模板

第一章&#xff1a;GIL消失后的并发危机全景图当CPython的全局解释器锁&#xff08;GIL&#xff09;真正消失&#xff0c;Python将首次具备原生、安全的多线程并行执行能力。但这并非一劳永逸的性能飞跃&#xff0c;而是一场系统级并发范式的重构风暴——内存模型、对象生命周期…...