Sql Server 存储过程删除一个表里(除ID外)完全重复的数据记录


 1 CREATE PROCEDURE P_DeleteSameData
 2 (
 3     @table nvarchar(50),--表名
 4      @columns nvarchar(200)--列名,格式形如:Id,Name,Age
 5  )
 6  AS
 7  BEGIN
 8      BEGIN TRY
 9           BEGIN TRANSACTION
10              DECLARE @SQL NVARCHAR(1000),@tempTable NVARCHAR(20);
11              SET @SQL = '';
12              IF OBJECT_ID('[#tempTable]') IS NOT NULL
13              BEGIN
14                  --PRINT 'aaa'
15                  SET @SQL = @SQL + 'DROP TABLE [dbo].[#tempTable]';
16              END
17              SET @tempTable = '[#tempTable]';
18              SET @SQL = @SQL + 'SELECT * INTO '+@tempTable+' FROM '+@table+' WHERE 1<>1;';
19 
20              --创建忽略重复列数据的临时表索引
21              SET @SQL = @SQL + 'CREATE UNIQUE INDEX tempIndex ON '+@tempTable+'(' + @columns + ') WITH IGNORE_DUP_KEY;';  
22                        
23              --将源表中的数据插入临时表中,同时会忽略重复列的数据,所以此时临时表中的数据已经是去重的数据了
24              SET @SQL = @SQL + 'INSERT INTO '+@tempTable+'('+@columns+') SELECT ' + @columns + ' FROM ' + @table + ';';        
25                   
26              --清空源表数据
27              SET @SQL = @SQL + 'TRUNCATE TABLE ' + @table + ';';
28              --将临时表中的数据再复制到源表中
29              SET @SQL = @SQL + 'INSERT INTO '+@table+'('+@columns+') SELECT '+@columns+' FROM '+@tempTable+';';
30              SET @SQL = @SQL + 'DROP TABLE '+@tempTable + ';';
31          --动态执行上面的所有语句
32              EXEC(@SQL);
33  
34          COMMIT TRANSACTION
35      END TRY
36      BEGIN CATCH
37          ROLLBACK TRANSACTION
38          DECLARE @msg nvarchar(4000)
39          SET @msg=error_message();
40          RAISERROR(@msg,11,1)
41          RETURN 1;
42      END CATCH
43  END
View Code


 

执行示例代码如下:

1 EXEC P_DeleteSameData @table = 'T_Teacher', @columns='Name,Age'

使用上述存储过程时要注意的是:

1.如果去重的表主键ID为自动增长或者自动生成GUID,即该表不可能在该列产生重复,则不能把该ID列传入@columns里,形如:@columns='StuName,StuAge,StuSex',

如果要满足该表所有列都要求不重复则:@columns='StuID,StuName,StuAge,StuSex'这样的形式。

2.有的同学或者同仁要问为什么要把所有的语句拼接到一起在最后执行?因为中间是用了临时表,而临时表的作用域(作用域是计算机编程里的一个术语,如果你有幸看到此篇文章,相信大家都懂得~)只能在同一个动态语句中,所以在最后连带临时表一起动态执行。还有一个办法就是可以使用全局临时表,不过耗费资源,所以不推荐。

原文地址:https://www.cnblogs.com/Leawee/p/4262975.html