Update Statement in a Stored Procedure
I have a stored Procedure called Active and the code is:
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
S开发者_Go百科ET @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
The problem is I am using thsi procedure in another procedure so Everytime that Procedure runs this procedure also runs and does the update to whole table.
The main reason for that update is to check for the duplicates on the table and set the duplicates to 0 and remaining to 1.
I dont want to run this update for whole table but I want the update to run only for Active duplicates.
Is there a way to do it?
To reiterate your issue. You are calling the above stored procedure from another stored procedure. I assume that the parent procedure is what is determining what you call "Active duplicates". If that is the case, then you have a few options:
1) Temp table, have the first procedure create a global temporary table and use it in nested procedure. Make sure to clean up after.
--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) Parameter, pass a comma separated list to the nested procedure and filter with IN
or EXISTS
clause. Not very scalable. (See added parameter and last line of query)
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) Add logic to your dynamic SQL to fetch the proper results. (See last line, which was appended. I cannot determine for you what that logic may be.)
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'
精彩评论