我正在创建一个记录车辆移动,清理,维修等的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然后以某种方式在更改后再次更新它们?!?
欢迎任何想法或问题。
提前致谢
答案 0 :(得分:1)
在我回答你的问题之前,我必须指出这一点:
where Callsign = '"+callsignString+"'"
这称为SQL连接,它允许SQL注入,这是当今软件中的#1 security vulnerability。永远不要这样做。始终使用parametrized SQL queries。
现在回答你的问题。
每次打开和关闭连接都会减慢一切。
这可能是正确的,但在您决定优化之前,您应该获得性能问题的证明。
像@PaulF提到的那样,您不需要每次都关闭连接。移动打开的代码并关闭循环外的连接。
另一种技术是在数据库中创建一个stored procedure,它将在TSQL中执行所有这些逻辑。这样,您只能提供存储过程的呼号,它将在单个SQL命令中执行所有84个操作。这种方法的缺点是存储过程的维护和重构通常要贵一些。