存储过程中的更新语句

发布于 2024-11-06 03:25:45 字数 1167 浏览 5 评论 0 原文

我有一个名为 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 

问题是我在另一个过程中使用该过程,因此每次该过程运行时,该过程也会运行并对整个表进行更新。

该更新的主要原因是检查表中的重复项,并将重复项设置为 0,将剩余项设置为 1。

我不想对整个表运行此更新,但我希望更新仅针对活动重复项运行。

有办法做到吗?

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


        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 

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

痞味浪人 2024-11-13 03:25:45

重申一下你的问题。您正在从另一个存储过程调用上述存储过程。我假设父过程决定了您所说的“活动重复项”。如果是这种情况,那么您有几个选择:

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'

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'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文