在本篇中,学习与练习SQL知识,程序中提供用户批量上传数据。在上传时也许会有网络中断,上传一部分,再重新上传。这样会有数据重复。
或者是需要对原有数据进行批量修改,删除等,要如何进行。
下面Insus.NET举个简单的例子。
先是在数据库创建一张表,是用来存储用户上传的数据。
CREATE TABLE [dbo].[Network_Register] ( [ID] INT NOT NULL, [NAME] NVARCHAR(20) NULL, [MAC] VARCHAR(17) NULL, [IPv4] VARCHAR(15) NULL )Source Code
直接在数据库添加几笔记录作为原始数据。
INSERT INTO [dbo].[Network_Register] ([ID],[NAME],[MAC],[IPv4]) VALUES (11,'','48-A3-80-78-CC-EC',''), (12,'','44-C3-46-E0-CA-6D',''), (16,'','30-84-54-9D-18-2F',''), (17,'','84-9F-B5-A7-EF-65',''), (20,'','88-36-5F-B4-55-3D','') SELECT [ID],[NAME],[MAC],[IPv4] FROM [dbo].[Network_Register]Source Code
既然是批量上传,使用表类型作为存储过程的参数,先创建一个表类型,这个表类型跟上面的数据表的结构一样:
CREATE TYPE [dbo].[udtt_NetworkRegister] AS TABLE ( [ID] INT NULL, [NAME] NVARCHAR(20) NULL, [MAC] VARCHAR(17) NULL, [IPv4] VARCHAR(15) NULL ) GOSource Code
CREATE PROCEDURE [dbo].[usp_Network_Register_BlukInsert] ( @bulk_data [dbo].[udtt_NetworkRegister] READONLY ) AS BEGIN MERGE [dbo].[Network_Register] AS Target USING (SELECT [ID],[NAME],[MAC],[IPv4] FROM @bulk_data) AS Source ON (Target.[ID] = Source.[ID]) WHEN MATCHED THEN UPDATE SET target.[NAME] = source.[NAME],target.[MAC] = source.[MAC],target.[IPv4] = source.[IPv4] WHEN NOT MATCHED BY TARGET THEN INSERT ([ID],[NAME],[MAC],[IPv4]) VALUES ([ID],[NAME],[MAC],[IPv4]); END GOSource Code
存储过程的主体,使用了MERGE的功能,判断上传的数据与原有数据进行按条件匹对。
相同MATCHED的更新,不相同NOT MATCHED的添加。
下面的数据是新上传的数据,高亮的ID是数据库表已经存在的数据:
DECLARE @network_data AS [dbo].[udtt_NetworkRegister] INSERT INTO @network_data SELECT [ID],[NAME],[MAC],[IPv4] FROM ( VALUES (11,'IT00003','48-A3-80-78-CC-EC','10.0.0.33'), (12,'','44-C3-46-E0-CA-6D','192.168.3.22'), (13,'IT06531','EC-01-EE-2E-92-BE','127.0.0.1'), (14,'','E4-46-DA-E8-0F-31',''), (15,'IT45311','60-91-F3-A7-3E-4B',''), (16,'IT43420','30-84-54-9D-18-2F','192.168.0.55'), (17,'IT67543','84-9F-B5-A7-EF-65',''), (18,'','20-5D-47-81-64-FE','10.0.2.78'), (19,'IT43457','88-28-B3-6A-E9-36','10.6.0.43'), (20,'IT76738','88-36-5F-B4-55-3D','') ) AS T([ID],[NAME],[MAC],[IPv4]) EXECUTE [dbo].[usp_Network_Register_BlukInsert] @network_data GOSource Code
现在我们再次SELECT查询数据,得到的数据如下: