【问题标题】:logging ONLY effected rows in sql update procedure在 sql 更新过程中仅记录受影响的行
【发布时间】:2013-04-25 05:45:05
【问题描述】:

我有一个更新表中 x 行数的过程。我创建了一个日志表,其中包含所有更新行的记录。所以每次我运行我的程序时,它都会产生影响。 5 行,然后这 5 行将被插入到我的日志表中。

这是我的程序:

UPDATE dbo.ImportAdvTemp
SET dbo.ImportAdvTemp.DeliveryAdrID = dbo.ImportAdvTemp_IMPORTED.DeliveryAdrID
FROM dbo.ImportAdvTemp, dbo.ImportAdvTemp_IMPORTED
WHERE 
    ISNULL(dbo.ImportAdvTemp.DeliveryName, '') = ISNULL(dbo.ImportAdvTemp_IMPORTED.DeliveryName, '') AND
    ISNULL(dbo.ImportAdvTemp.DeliveryStreet,'') = ISNULL(dbo.ImportAdvTemp_IMPORTED.DeliveryStreet, '') AND
    ISNULL(dbo.ImportAdvTemp.DeliveryHouseNumber, '') = ISNULL(dbo.ImportAdvTemp_IMPORTED.DeliveryHouseNumber, '') AND
    ISNULL(dbo.ImportAdvTemp.DeliverySubCity, '') = ISNULL(dbo.ImportAdvTemp_IMPORTED.DeliverySubCity, '') AND
    ISNULL(dbo.ImportAdvTemp.DeliveryPostCode, '') = ISNULL(dbo.ImportAdvTemp_IMPORTED.DeliveryPostCode, '') AND
    ISNULL(dbo.ImportAdvTemp.DeliveryCity, '') = ISNULL(dbo.ImportAdvTemp_IMPORTED.DeliveryCity, '') AND
    ISNULL(dbo.ImportAdvTemp.DeliveryCountry, '') = ISNULL(dbo.ImportAdvTemp_IMPORTED.DeliveryCountry, '') AND
    ISNULL(dbo.ImportAdvTemp.DeliveryCustomer, '') = ISNULL(dbo.ImportAdvTemp_IMPORTED.DeliveryCustomer, '') AND
    ISNULL(dbo.ImportAdvTemp.DeliveryAlias, '') = ISNULL(dbo.ImportAdvTemp_IMPORTED.DeliveryAlias, '') AND
    ISNULL(dbo.ImportAdvTemp.DeliveryNote, '') = ISNULL(dbo.ImportAdvTemp_IMPORTED.DeliveryNote, '') AND
    dbo.ImportAdvTemp.toManualProc = 1 and dbo.ImportAdvTemp.Closed = 0 and(dbo.ImportAdvTemp.DeliveryAdrID IS NULL or dbo.ImportAdvTemp.PickupAdrID IS NULL or dbo.ImportAdvTemp.DeliveryAdrID = 0 or dbo.ImportAdvTemp.PickupAdrID = 0)

我需要确定哪些行受到影响,然后使用该行中的数据插入到我的日志表中。我已经阅读了有关使用游标的信息,这是唯一的方法吗?

【问题讨论】:

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


    【解决方案1】:

    我对 sqlserver 了解不多,但在 Oracle 中最直接的解决方案是 UPDATE 触发器,它插入到日志表中,我相信您可以在 sqlserver 中执行相同的操作。

    触发器的好处是它不会影响您在代码中的作用,它会执行真正的工作(更新)。您可以禁用或更改触发器而不会弄乱主代码,它只会影响日志记录方面。

    附带说明,您可能需要考虑这样的情况,即更新了一行(因为它与 WHERE 子句匹配),但新旧值是相同的。您是否希望记录此内容,或者您​​是否通过编写适当的 WHERE 子句来防止这种情况发生?您想要记录旧的、新的或两个值吗?无论日志实现如何,您都必须回答这个问题。

    【讨论】:

    • 我只想记录更新的行。此过程将用于自动验证记录。我将有一个目录表。此表将包含手动验证的行。如果再次插入具有相同 vsalues 的行,则用户不必验证它,它将自动验证。那么当一行或多行受到影响时,触发器如何“知道”?
    • 您需要一个 FOR EACH ROW 触发器。它将为每个受影响的行触发一次。不过我这里说的是Oracle,不知道SQLSERVER有没有FOR EACH ROW触发器。
    • 我不这么认为。触发器附加到一个表上,并且独立于您的过程,即它会记录更新,无论它们是由您的过程还是从其他地方启动的。
    • 它是因为我必须记录其他表中的所有信息。所以我需要将列数据插入到我的日志表中。
    • 您确定必须这样做吗?记录真正更新的表的更改还不够吗?我需要其他表中的列值,您可以随时将日志加入这些表中
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-29
    • 1970-01-01
    • 2019-11-20
    • 2011-06-11
    • 1970-01-01
    • 2010-11-15
    相关资源
    最近更新 更多