更新存储过程中的语句

时间:2011-05-10 20:41:58

标签: sql sql-server sql-server-2008 stored-procedures dynamic-sql

我有一个名为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重复项运行。

有办法吗?

1 个答案:

答案 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)参数,将逗号分隔列表传递给嵌套过程,并使用INEXISTS子句进行过滤。不太可扩展。 (参见添加的参数和查询的最后一行)

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'