我有一个名为Active的存储过程,代码为:
CREATE PROCEDURE dbo.Active
(
@ID INT ,
@Source VARCHAR(25)
)
AS
BEGIN
DECLARE @SQL NVARCHAR(MAX)
DECLARE @SchemaName SYSNAME
DECLARE @TableName SYSNAME
DECLARE @DatabaseName SYSNAME
DECLARE @BR CHAR(2)
SET @BR = CHAR(13) + CHAR(10)
SELECT @SchemaName = Source_Schema ,
@TableName = Source_Table ,
@DatabaseName = Source_Database
FROM Source
WHERE ID = @ID
SET @SQL = 'UPDATE Source_Table' + @BR
+ 'SET __ACTIVE = CASE WHEN rn = 1 THEN 1 ELSE 0 END' + @BR
+ 'FROM ( ' + @BR + 'SELECT ROW_NUMBER() OVER (PARTITION BY '
+ @Source + ' ORDER BY __REC_ID DESC) AS rn
, * FROM ' + @DatabaseName + '.' + @SchemaName + '.' + @TableName
+ @BR + ') Source_Table' + @BR
EXEC @SQL
END
问题是我在另一个过程中使用thsi过程因此每次过程运行此过程也会运行并对整个表进行更新。
更新的主要原因是检查表格上的重复项,并将重复项设置为0并保留为1.
我不想为整个表运行此更新,但我希望更新仅针对Active重复项运行。
有办法吗?
答案 0 :(得分:2)
重申你的问题。您正在从另一个存储过程调用上述存储过程。我假设父程序正在决定你所谓的“活动重复”。如果是这种情况,那么您有几个选择:
1)临时表,让第一个过程创建一个全局临时表并在嵌套过程中使用它。确保在之后进行清理。
--Base procedure creates global temp table with proper values;
SELECT ID
INTO ##ActiveDups
FROM DUPTABLE
WHERE SOMECONDITION = SOMECONDITION
--Join global temp table on query
SET @SQL = 'UPDATE Source_Table' + @BR
+ 'SET __ACTIVE = CASE WHEN rn = 1 THEN 1 ELSE 0 END' + @BR
+ 'FROM ( ' + @BR + 'SELECT ROW_NUMBER() OVER (PARTITION BY '
+ @Source + ' ORDER BY __REC_ID DESC) AS rn
, * FROM ' + @DatabaseName + '.' + @SchemaName + '.' + @TableName
+ @BR + ') Source_Table' + @BR
+ ' INNER JOIN ##ActiveDups ad ON ad.ID = Source_Table.ID'
--Drop global temp table
DROP TABLE ##ActiveDups
2)参数,将逗号分隔列表传递给嵌套过程,并使用IN
或EXISTS
子句进行过滤。不太可扩展。 (参见添加的参数和查询的最后一行)
CREATE PROCEDURE dbo.Active
(
@ID INT ,
@Source VARCHAR(25),
@List VARCHAR(MAX)
)
--...
SET @SQL = 'UPDATE Source_Table' + @BR
+ 'SET __ACTIVE = CASE WHEN rn = 1 THEN 1 ELSE 0 END' + @BR
+ 'FROM ( ' + @BR + 'SELECT ROW_NUMBER() OVER (PARTITION BY '
+ @Source + ' ORDER BY __REC_ID DESC) AS rn
, * FROM ' + @DatabaseName + '.' + @SchemaName + '.' + @TableName
+ @BR + ') Source_Table' + @BR
+ ' WHERE SOMECONDITION IN ' @List
3)为动态SQL添加逻辑以获取正确的结果。 (见最后一行,附后。我无法确定你的逻辑是什么。)
SET @SQL = 'UPDATE Source_Table' + @BR
+ 'SET __ACTIVE = CASE WHEN rn = 1 THEN 1 ELSE 0 END' + @BR
+ 'FROM ( ' + @BR + 'SELECT ROW_NUMBER() OVER (PARTITION BY '
+ @Source + ' ORDER BY __REC_ID DESC) AS rn
, * FROM ' + @DatabaseName + '.' + @SchemaName + '.' + @TableName
+ @BR + ') Source_Table' + @BR
+ ' WHERE SOMECONDITION = SOMECONDITION'