记录以下数据的最佳方式

时间:2017-06-01 15:23:09

标签: c# asp.net sql-server

我正在创建一个记录车辆移动,清理,维修等的SQL Server数据库。

我正在努力研究如何记录以下数据。

我需要在每次清洁车辆时进行记录。我还需要提取过去28天内清洁车辆的时间并取平均值

到目前为止,我有一个包含以下列的主表:

Callsign, Registration, Location, Date Last Cleaned.

然后,作为一个解决方案我有"车辆特定"这些表是我每次清理时记录的地方。

然而,当我在使用ASP.net时,我能找到访问干净日期的唯一方法是在每个车辆表中执行foreach循环并返回过去28天内的日期计数。这个问题我无法弄清楚如何在1个数据连接中做这个而不是多个请求到服务器。

以下是代码片段,但您可以看到它贯穿每个复选框列表,如果" true"然后将添加到车辆特定表

 string constr = myconstring;

 SqlConnection cnn = new SqlConnection(constr);
 SqlTransaction transaction;

 for (int i = 0; i < checkboxlistAM.Items.Count; i++)
 {
     string callsignString = checkboxlistAM.Items[i].Text;

     if (checkboxlistAM.Items[i].Selected == true)
     {
         string declare = "declare @morning datetime declare @date datetime declare @counting int ";
         string setting = " set @date = DATEADD(d, DATEDIFF(d, 0, getdate()), 0) set @morning = dateadd(hh, 7, @date) set @counting = (select count([made ready]) from["+callsignString+"] where[Made Ready] = @morning) ";
         string insertmorning = " if @counting <>1 insert into ["+callsignString+"] ([made ready]) values (@morning) ";

         string QueryVehicleSpecificTable = declare + setting + insertmorning;
         string QueryMasterTable = "update Shropshire SET[last made Ready AM] = GETDATE() where Callsign = '"+callsignString+"'";

         cnn.Open();
         transaction = cnn.BeginTransaction();

         SqlCommand cmd1 = new SqlCommand(QueryVehicleSpecificTable, cnn);
         cmd1.CommandType = CommandType.Text;

         SqlCommand cmd2 = new SqlCommand(QueryMasterTable, cnn);
         transaction.Commit();

         cmd1.ExecuteNonQuery();
         cmd2.ExecuteNonQuery();

         cnn.Close();
     }
     else if (checkboxlistAM.Items[i].Selected == false)
     {
         string declare = "declare @morning datetime declare @date datetime declare @counting int ";
         string setting = " set @date = DATEADD(d, DATEDIFF(d, 0, getdate()), 0) set @morning = dateadd(hh, 7, @date) set @counting = (select count([made ready]) from[" + callsignString + "] where[Made Ready] = @morning) ";
         string deletemorning = " delete from ["+callsignString+"] where [Made Ready] = @morning";
         string queryDeleteRecordfromVehicleSpecific = declare + setting + deletemorning;
         string QueryMasterTable = "update Shropshire SET[last made Ready AM] = null where Callsign = '" + callsignString + "'";

         cnn.Open();
         transaction = cnn.BeginTransaction();

         SqlCommand cmd1 = new SqlCommand(QueryMasterTable, cnn);
         SqlCommand cmd2 = new SqlCommand(queryDeleteRecordfromVehicleSpecific, cnn);

         cmd1.CommandType = CommandType.Text;
         cmd2.CommandType = CommandType.Text;

         transaction.Commit();

         cmd1.ExecuteNonQuery();
         cmd2.ExecuteNonQuery();
         cnn.Close();
     }
}

正如你所看到的,这个循环有大约。在早上和下午进行42次迭代(共84次),每次打开和关闭连接都会减慢一切。

有没有人对我如何做得更好有任何想法。

通过制作新的&#34;清洁&#34;表,但是我怎样才能跟踪28天而不是永远。

或者通过复制每个&#34;车辆特定表格&#34;到1 DataTable然后以某种方式在更改后再次更新它们?!?

欢迎任何想法或问题。

提前致谢

1 个答案:

答案 0 :(得分:1)

在我回答你的问题之前,我必须指出这一点:

where Callsign = '"+callsignString+"'"

这称为SQL连接,它允许SQL注入,这是当今软件中的#1 security vulnerability。永远不要这样做。始终使用parametrized SQL queries

现在回答你的问题。

  

每次打开和关闭连接都会减慢一切。

这可能是正确的,但在您决定优化之前,您应该获得性能问题的证明。

像@PaulF提到的那样,您不需要每次都关闭连接。移动打开的代码并关闭循环外的连接。

另一种技术是在数据库中创建一个stored procedure,它将在TSQL中执行所有这些逻辑。这样,您只能提供存储过程的呼号,它将在单个SQL命令中执行所有84个操作。这种方法的缺点是存储过程的维护和重构通常要贵一些。