1

首先,我是安全人员,而不是开发人员。如果有更简单的方法来做我想做的事,我不会感到惊讶。这是我第一次在 C# 中做任何事情,所以要温柔。

我正在开发一个数据库来跟踪我们对审计控制的遵守情况。数据库是 MS SQL 2008,带有我用 C# 编写的 Web 应用程序前端。我正在开发一个页面,该页面允许用户使用测试结果更新控件或更改要求或几乎其他任何内容。在此页面上更新信息时,我试图在更新 Controls 表中的记录之前将现有数据从 Controls 表写入 History 表。我也在尝试记录(在History表格中)谁进行了更新以及何时进行更新。这是我遇到问题的地方。我可以在语句中嵌套一个SELECT语句INSERT来提取数据,但我无法弄清楚如何添加更新日期和时间以及更新它的用户。

这是我目前的查询,由于明显的原因它不起作用。只是为了让您了解我正在使用的列和参数。

INSERT INTO History (BUName, ControlFWName, ControlID, ControlDesc, 
                     TestPlan, TestFreq, NextTest, ControlCatName,
                     AuditorNotes, AuditorNoteTime, TestResults, ArtifactID1, 
                     ArtifactID2, ArtifactID3, ArtifactID4, 
                     WhoChanged, WhenChanged) 
                     SELECT BUName, ControlFWName, ControlID, ControlDesc, 
                            TestPlan, TestFreq, NextTest, ControlCatName, 
                            AuditorNotes, AuditorNoteTime, TestResults, ArtifactID1, 
                            ArtifactID2, ArtifactID3, ArtifactID4 
                     FROM Controls 
                     WHERE BUName = @BUName 
                       AND ControlFWName = @ControlFWName 
                       AND ControlID = @ControlID

如何将WhoChangedandWhenChanged列附加到该插入语句?它们被参数化为只是DateTime.Now和的变量User.Identity.Name

如果您需要更多代码,请告诉我。

4

2 回答 2

2

这是我第一次在 C# 中做任何事情,所以要温柔。

但这是一个 T-SQL 而不是 C# 问题,不是吗?

您只需将参数添加到查询中:

INSERT INTO history 
            (buname, controlfwname,  controlid, controldesc, 
             testplan, testfreq, nexttest, controlcatname, 
             auditornotes, auditornotetime, testresults, 
             artifactid1, artifactid2, artifactid3, artifactid4, 
             whochanged, whenchanged) 
SELECT buname, controlfwname, controlid, controldesc, 
       testplan, testfreq, nexttest, controlcatname, 
       auditornotes, auditornotetime, testresults, 
       artifactid1, artifactid2, artifactid3, artifactid4, 
       @WhoChanged, @WhenChanged 
FROM   controls 
WHERE  buname = @BUName 
       AND controlfwname = @ControlFWName 
       AND controlid = @ControlID 

这里是 C# 部分,虽然不清楚为什么它可能很重要:

string sql = @"INSERT INTO history 
             (buname, controlfwname,  controlid, controldesc, 
             testplan, testfreq, nexttest, controlcatname, 
             auditornotes, auditornotetime, testresults, 
             artifactid1, artifactid2, artifactid3, artifactid4, 
             whochanged, whenchanged) 
SELECT buname, controlfwname, controlid, controldesc, 
       testplan, testfreq, nexttest, controlcatname, 
       auditornotes, auditornotetime, testresults, 
       artifactid1, artifactid2, artifactid3, artifactid4, 
       @WhoChanged, @WhenChanged 
FROM   controls 
WHERE  buname = @BUName 
       AND controlfwname = @ControlFWName 
       AND controlid = @ControlID";

// use the using statement to ensure that unmanaged resources are disposed and the connection is closed
using(var con = new SqlConnection(connectionString))
using (var cmd = new SqlCommand(sql, con))
{
    DateTime now = DateTime.Now;
    string user = HttpRequest.Current.User.Identity.Name;
    cmd.Parameters.AddWithValue("@WhoChanged", user);
    cmd.Parameters.AddWithValue("@WhenChanged", now);
    // ...
    con.Open();
    int affectedRecords = cmd.ExecuteNonQuery();
}
于 2013-05-16T21:09:47.407 回答
0

我认为您可以走几条不同的路线。您可以使用存储过程或触发器来解决问题。

存储过程为您提供了很多控制权。您可以接受您想要的任何参数并运行一系列 INSERT 和 UPDATE 语句等。它将您的所有代码放在一个很好的存档位置。不要忘记内联注释。

触发器的最大优点是始终运行。您的一位同事是否有机会访问数据表并修改数据?如果您的应用程序使用存储过程,则历史表和控件表可能会不同步。那是问题吗?

(顺便说一句,我会考虑将 WhoChanged 和 WhenChanged 添加到您的控件表中。然后您可以在修改之前将整个控件行简单地写入历史表中。这可以通过触发器或存储过程来完成。

编辑

需要明确的是,您何时创建历史记录?您是否在每个 INSERT 和 UPDATE 上创建它们?只想确保每条记录都标有创建该数据的 ID/时间戳。如果您只是在数据已过时时将数据移动到历史记录表中,那么您将使用有关删除人员和删除时间的信息对其进行标记。这可能会让后来的人感到困惑。

于 2013-05-16T21:17:56.717 回答