开发者

Update Statement in a Stored Procedure

开发者 https://www.devze.com 2023-03-05 10:09 出处:网络
I have a stored Procedure called Active and the code is: CREATE PROCEDURE dbo.Active ( @ID INT , @Source VARCHAR(25)

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'
0

精彩评论

暂无评论...
验证码 换一张
取 消