前面删除未设置主键的表里的重复记录这篇文章里写过一个存储过程,可以删除指定表的重复记录,后来想想,如果每个表都要这么改改也太麻烦了,就想写个通用点的,也就是说该存储过程接收表名和列名作为参数,其中表明指定该数据库中的含有重复记录的表,列名是指要作为主键不能有相同值的 列。
先是作为实验品的表:
CREATE TABLE [dbo].[tbl1] ( [item_number] [int] NULL , [item_quality] [int] NULL ) ON [PRIMARY]
然后输入几条记录做实验,多执行几遍一下的代码:
insert into tbl1 values(1,2) insert into tbl1 values(1,3) insert into tbl1 values(1,4) insert into tbl1 values(2,2) insert into tbl1 values(3,3) insert into tbl1 values(3,5)
首先要解决的问题是,如何动态构建和执行含有输入参数的SQL语句,为此我做了下面的一个存储过程实验。
create proc test_string as declare @column_name varchar(50) declare @table_name varchar(50) declare @column_value int declare @sql_variant sql_variant declare @sql1 Nvarchar(1024) select @column_value=2 select @column_name='item_number' select @table_name='tbl1'
--下面两句是关键 set @sql1='select @sql_variant='+@column_name + ' from '+@table_name+' where '+@column_name+'=@column_value ' exec sp_executesql @sql1,N'@sql_variant sql_variant output,@column_value int',@sql_variant output,@column_value select @sql_variant
为了在试验的时候节省时间,我直接在过程里面定义了变量存储表名和列名,这个和真实执行的时候写参数没有质的区别。其中用到了exec sp_executesql ,具体语法可以参考我的另一篇的Transact-SQL 参考之sp_executesql。
这里面有一个点需要注意,定义的@sql1变量一定要定义成nvarchar类型,少了那个N就会报错。
这个例子验证的结果就是解决了上面提出的问题。
另外,补充一下,之所以不用exec是因为得不到返回值,
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
就像最后一句,可以得到答案,但是无法将其赋值给其它变量,所以舍弃。