【问题标题】:Audit Table - Case Statement审计表 - 案例陈述
【发布时间】:2013-12-24 06:28:52
【问题描述】:

我想要达到的目标:

当有人使用(RegNum、VinNumber、CarMakeID 等)更新 Car 表时,我需要将其放入审计表中。

在下面的示例中,我选择了 CarID = 1 和 ChangeItem = 1(我希望代码使用案例的第一部分)。

如果我要选择 ChangeItem2,我希望它更新 Car Table 中的 VinNumber,并将 deleted.VinNumber 和 Inserted.VinNumber 插入到审计表中。

DECLARE @CarID INT
DECLARE @ChangedItem INT
DECLARE @Input VARCHAR(50)


SET @CarID  = 1
SET @ChangedItem = 1
SET @Input = 'LR44 GH345'

    UPDATE CAR
(   
CASE
        WHEN @ChangedItem = 1 THEN
        SET RegNum = @Input
        OUTPUT @CarID, @ChangedItem, deleted.RegNum, inserted.RegNum INTO CarAudit  (CarID, CarAuditObjectID, OldValue ,NewValue)
        WHERE CarID = @CarID

        WHEN @ChangedItem = 2 THEN
        SET VinNumber = @input
        OUTPUT @CarID, @ChangedItem, deleted.RegNum, inserted.RegNum INTO CarAudit  (CarID, CarAuditObjectID, OldValue ,NewValue)
        WHERE CarID = @CarID

END
)

如果有人有更好的方法完全做到这一点,请分享,我并不拘泥于这种设计。

非常感谢您的帮助。

杰。

【问题讨论】:

    标签: sql case audit


    【解决方案1】:

    对于任何偶然发现这一点的人。

    我想避免使用触发器,所以用下面的代码把它作为一个存储过程:

    DECLARE @CarID INT
    DECLARE @ChangedItem INT
    DECLARE @Input VARCHAR(50)
    
    
    SET @CarID  = 1
    SET @ChangedItem = 2
    SET @Input = 'PG 542DF 07GD 11'
    
    
    IF @ChangedItem = 1
    
        BEGIN
    
            UPDATE CAR
            SET RegNum = @Input
            OUTPUT @CarID, @ChangedItem, deleted.RegNum, inserted.RegNum INTO CarAudit  (CarID, CarAuditObjectID, OldValue ,NewValue)
            WHERE CarID = @CarID
    
        END
    
    IF @ChangedItem = 2
    
        BEGIN
            UPDATE CAR
            SET VINNumber = @Input
            OUTPUT @CarID, @ChangedItem, deleted.RegNum, inserted.RegNum INTO CarAudit  (CarID, CarAuditObjectID, OldValue ,NewValue)
            WHERE CarID = @CarID
        END
    

    【讨论】:

      【解决方案2】:

      我仍然建议使用触发器,它比您在存储过程中必须做的要干净一些。但是,如果您想坚持使用存储过程,您可以使用以下模式...(代码下方的说明)

      Declare @ColumnName varchar(250)
      Declare @Input varchar(250)
      Declare @CarID int
      
      Select @ColumnName = 'RegNum'
      Select @Input = 'LR44 GH345'
      select @CarID = 1
      
      Begin Transaction
      Declare @DynamicSQL varchar(max)
      
      Select * Into #CarAuditTemp
      From Car
      Where CarID = @CarID
      
      Select @DynamicSQL = '
      Update Car
      Set '+ @ColumnName +' = "'+ @Input +'"
      Where CarID = '+ Convert(Varchar, @CarID) +' 
      '
      
      
      Select @DynamicSQL
      --Execute (@DynamicSQL)
      
      Select @DynamicSQL = '
      Insert CarAudit
      (CarID, ChangedItem, OldValue, NewValue)
      Select  '+ Convert(Varchar, @CarID) +',
          "'+ @ColumnName +'",
          #CarAuditTemp.'+ @ColumnName +',
          Car.'+ @ColumnName +'
      From Car
      Inner Join #CarAudit
          On Car.CarID = #CarAuditTemp.CarID
      '
      
      Select @DynamicSQL
      --Execute (@DynamicSQL)
      Commit Transaction
      

      @ColumnName、@Input 和@CarID 都是存储过程的参数。这将使用动态 SQL,以便您可以生成必要的 SQL 以使用您的值更新表并插入到审计表中。我在动态 sql 变量上注释掉了执行和左选择,以便您可以看到它的行为方式。 #CarAuditTemp 临时表用于在更新任何内容之前获取记录的原始状态。在执行任何其他操作之前,最好还进行一些错误检查,确保传入存储过程的列存在于该表中,确保传入的 CarID 也存在于表中。我添加了一个事务,因为如果在更新 Car 或插入 CarAudit 期间发生错误,您需要回滚所有内容。这只是您需要做什么的大致思路,如果您有任何问题,请告诉我。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-08
        • 2012-08-11
        • 2023-04-10
        • 2010-10-30
        • 2016-05-13
        • 2016-02-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多