当前位置: 首页 > 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…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器

一、原理介绍 传统滑模观测器采用如下结构&#xff1a; 传统SMO中LPF会带来相位延迟和幅值衰减&#xff0c;并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF)&#xff0c;可以去除高次谐波&#xff0c;并且不用相位补偿就可以获得一个误差较小的转子位…...