通过SQL脚本导入数据到不同数据库避免重复导入三种方式

简介: 前言 无论何种语言,一旦看见代码中有重复性的代码则想到封装来复用,在SQL同样如此,若我们没有界面来维护而且需要经常进行的操作,我们会写脚本避免下次又得重新写一遍,但是这其中就涉及到一个问题,这个问题我开始也没太在意,直到某时某刻,老大看到我写的脚本后笑着问了一句,你的脚本可否重复执行,我懵逼了,很显然不能,如果不能避免这种情况发生,比如进行插入操作,当下次其他同事来执行其脚本时可能会插入重复数据,如果是在线上那就傻逼了,所以老大又给我上了一课,从此之后每次写脚本都加逻辑判断,是的,也就是可重复执行。

前言

无论何种语言,一旦看见代码中有重复性的代码则想到封装来复用,在SQL同样如此,若我们没有界面来维护而且需要经常进行的操作,我们会写脚本避免下次又得重新写一遍,但是这其中就涉及到一个问题,这个问题我开始也没太在意,直到某时某刻,老大看到我写的脚本后笑着问了一句,你的脚本可否重复执行,我懵逼了,很显然不能,如果不能避免这种情况发生,比如进行插入操作,当下次其他同事来执行其脚本时可能会插入重复数据,如果是在线上那就傻逼了,所以老大又给我上了一课,从此之后每次写脚本都加逻辑判断,是的,也就是可重复执行。接下来讲讲最近项目中遇到的场景。

话题引入

在国民成年人体质测试中需要计算成年年纪且体侧年龄为20-59岁,若当前日期未超过成年人出生日期则岁数减一,否则不减,例如一个成年人出生日期为1991-11-01,此时该成年人的体侧年龄为25岁,若为1991-10-01则体侧年龄为26岁,此为第一步。第二步则是分组,每个年龄阶段的人测试的项目不一样,即需要根据年龄进行分组,在体侧文档中分为3组,一组为男性20-39岁,一组为女性20-39,最后一组不分男女为40-59。最后我们需要做的是根据不同的年龄阶段和性别进行分组。我们建立如下表。

由上我们可以看出有20-39岁的男性,也有20-39岁的女性。也有40-59岁的男性等,关键在于我们怎么利用SQL根据国民成年人体质测试文档计算出上述成年人的实际年龄呢。

SELECT  Id ,
        DATEDIFF(YEAR, Birthday, GETDATE()) AS age ,
        Name
FROM    dbo.t1

看到上述查询明显不正确,未到出生日期的人年龄并未减掉1,此时我们可以利用DATEPART函数,第一个参数指定为dayofyear,此参数表明指定日期到在这一年的天数,例如我们想要获取当前已经过了多少天。

SELECT DATEPART(dayofyear, GETDATE())

SELECT DATEPART(dayofyear, '2017-12-31')

我们通过出生日期的天数和当前日期的天数,若大于当前日期天数则说明生日还未到,否则减掉1。

SELECT  Id ,
        DATEDIFF(YEAR, Birthday, GETDATE())
        - CASE WHEN DATEPART(DAYOFYEAR, Birthday) > DATEPART(DAYOFYEAR,
                                                             GETDATE()) THEN 1
               ELSE 0
          END Age ,
        Name
FROM    dbo.t1

此时我们完成了年龄阶段的区分,下面我们再插入到另外一个数据库它test2中。 这里我能想到的是两种种方式,若还有其他欢迎补充。

LEFT JOIN ....IS NULL

我们利用左连接来进行插入,同时若重复的话则另外需要插入的表主键必定不为NULL,所以我们外加NULL判断则可以去除重复插入问题。

INSERT  INTO test2.dbo.t2
        ( UserId ,
          Birthday ,
          Gender ,
          Name
        )
        SELECT  t1.Id ,
                t1.Birthday ,
                t1.Gender ,
                t1.Name
        FROM    dbo.t1 AS t1
                LEFT JOIN test2.dbo.t2 AS t2 ON t1.Id = t2.UserId
        WHERE   t2.Id IS NULL  

当再次执行时则返回受影响行数为0

NOT EXISTS/NOT IN

INSERT  INTO test2.dbo.t2
        ( UserId ,
          Birthday ,
          Gender ,
          Name
        )
        SELECT  t1.Id ,
                t1.Birthday ,
                t1.Gender ,
                t1.Name
        FROM    dbo.t1 AS t1  
        WHERE NOT EXISTS(SELECT t2.UserId
                    FROM test2.dbo.t2 t2
                   WHERE t2.UserId = t1.Id)
INSERT  INTO test2.dbo.t2
        ( UserId ,
          Birthday ,
          Gender ,
          Name
        )
        SELECT  t1.Id ,
                t1.Birthday ,
                t1.Gender ,
                t1.Name
        FROM    dbo.t1 AS t1  
        WHERE t1.Id NOT in (SELECT t2.UserId
                    FROM test2.dbo.t2 t2
                   WHERE t2.UserId = t1.Id)

总结 

本节我们讲述了利用写SQL脚本避免重复插入问题,同时来讲述了如何根据出生日期查询实际年龄。

目录
相关文章
|
SQL 关系型数据库 MySQL
MySql数据库中的视图,索引与数据库sql脚本如何导入与导出---(详细介绍)
MySql数据库中的视图,索引与数据库sql脚本如何导入与导出---(详细介绍)
373 0
|
SQL 关系型数据库 MySQL
MySQL数据库的数据导入和导出操作指南
MySQL数据库的数据导入和导出操作指南
|
2月前
|
SQL 关系型数据库 MySQL
数据库导入SQL文件:全面解析与操作指南
在数据库管理中,将SQL文件导入数据库是一个常见且重要的操作。无论是迁移数据、恢复备份,还是测试和开发环境搭建,掌握如何正确导入SQL文件都至关重要。本文将详细介绍数据库导入SQL文件的全过程,包括准备工作、操作步骤以及常见问题解决方案,旨在为数据库管理员和开发者提供全面的操作指南。一、准备工作在导
307 0
|
4月前
|
SQL 数据可视化 关系型数据库
成功解决7版本的数据库导入 8版本数据库脚本报错问题
您提供的链接是一篇关于如何解决在MySQL数据库中导入脚本时出现版本兼容性问题的博客文章。文章中提到,如果在MySQL 5.7之前的版本中使用utf8mb4_0900_ai_ci排序规则,会遇到"Unknown collation"错误。解决办法包括升级MySQL版本到8.0或更高,或者更改排序规则为utf8mb4_general_ci或utf8mb4_unicode_ci,并提供了修改SQL脚本的示例。 如果您需要更详细的信息或有其他问题,请告诉我。
|
SQL 数据库
navicat导入sql,数据库数据一直出错不能全部导入的问题解决方法
navicat导入sql,数据库数据一直出错不能全部导入的问题解决方法
346 0
navicat导入sql,数据库数据一直出错不能全部导入的问题解决方法
|
SQL 存储 关系型数据库
如何创建数据库(表),一个词,清爽(包括启动MySQL服务,数据库的增删改查,与数据的导入)
如何创建数据库(表),一个词,清爽(包括启动MySQL服务,数据库的增删改查,与数据的导入)
159 0
|
SQL 关系型数据库 MySQL
MySQL 导出 表结构,执行 .sql 文件导入结构或者数据
MySQL 导出 表结构,执行 .sql 文件导入结构或者数据
|
SQL Shell 数据库
shell 自动导出导入数据库,将导出的格式为 : 数据库名+时间.sql
mysqldump 自动导出mysql8 or mariadb10x 数据库工具,导入数据库工具,mysql 创建于删除数据库
187 0
|
SQL 数据库 数据库管理
数据库——数据库创建(模板与导入)
数据库——数据库创建(模板与导入)
数据库——数据库创建(模板与导入)
|
SQL 数据库
数据库——多种方法导入Excel数据
数据库——多种方法导入Excel数据
数据库——多种方法导入Excel数据