首页 > 解决方案 > 基于更新表的动态删除

问题描述

我想编写一个删除重复项的动态脚本。我想尝试避免使用 CURSOR,所以我一直在研究编写字符串,而不是在一个列中有表,在另一列中有相应的表属性。我也尝试过使用 WITH 的动态 SQL。但这就是我到目前为止所拥有的。我打算稍后将其用作动态 SQL 中的参数

东西的例子。但是,这会导致每一行都重复相同的列名:

select name as table_name,
    stuff(( select  ', ' +char(10)+ ac.[name] FROM DW.sys.columns ac 
            inner join DW.sys.tables t on ac.object_id=t.object_id
            where ac.name not in ('ModifiedOn','ValidFrom','ValidTo')
            FOR XML PATH('')
            ), 1, 1, '')
    from sys.tables 

我想要的是这个输出:

TableName || ColumnName  
table1    || aa,ab,ac      
table2    || ba,bb,bc    
table3    || ca,cb,cc   

我的想法是用这个来达到这个效果或类似:

'WITH DELETEDUPLICATE AS (
    SELECT '+@ColumnName+',
    ROW_NUMBER() OVER(PARTITION BY '+@ColumnName+' ORDER BY '+@ColumnName+') AS Duplicate_Row_Count
    FROM '+@TableName+'
    )
DELETE
FROM DELETEDUPLICATE
WHERE Duplicate_Row_Count > 1 

任何想法表示赞赏!

更新:根据 satishcse 的建议,我得到了我想要的桌子。我在动态 WITH 步骤中获取多行时遇到问题,所以我只是将该部分作为变量删除(删除了 'SET @WITH =' )。但是如何执行每一行呢?我现在得到的是:

删除重复的 AS(....

对于每行的每个表

标签: sqlsql-serverdynamicquery

解决方案


在 OpenQuery 中,您必须使用execute()函数运行查询。答案可以解决你的问题,但我不建议你使用 OpenQuery。

declare @query as nvarchar(max)

set
    @query = 
    'WITH DELETEDUPLICATE AS (
        SELECT '+@ColumnName+',
        ROW_NUMBER() OVER(PARTITION BY '+@ColumnName+' ORDER BY '+@ColumnName+') AS Duplicate_Row_Count
        FROM '+@TableName+'
        )
    DELETE
    FROM DELETEDUPLICATE
    WHERE Duplicate_Row_Count > 1'

execute(@query)

推荐阅读