我继承了一些与GP接口的代码。在调试问题之前查看代码时,我发现了一个撤消对一组表的更新的函数。
代码包含许多SQL命令,我想知道是否从单个存储过程获得更好的性能,输入参数是表 ds ,而不是在每行上运行所有这些命令表格分开。
private void revertSave()
{
try
{
SqlConnection conn = GetConnectionToGP();
if (conn != null)
{
using (SqlCommand cmd = new SqlCommand())
{
//records from InventoryTransaction Master, Detail, and Serial tables when window is opened.
foreach (DataRow dr in _ds.Tables[0].Rows)
{
cmd.Connection = conn;
//TRANSACTION tables
cmd.CommandText = "UPDATE InventoryTransaction_Master " +
"SET Completed = 0 WHERE DocumentNumber = " + SqlString(dr["DocumentNumber"].ToString().Trim());
cmd.ExecuteNonQuery();
cmd.CommandText = "UPDATE InventoryTransaction_Serial " +
"SET BIN = '' " +
"WHERE DocumentNumber = " + SqlString(dr["DocumentNumber"].ToString().Trim()) +
" and DocumentType = 1 and ItemNumber = " + SqlString(dr["PrefixedItemNumber"].ToString().Trim()) +
" and LineSequenceNumber = " + SqlString(dr["LineSequenceNumber"].ToString().Trim()) +
" and SerialNumber = " + SqlString(dr["SerialNumber"].ToString().Trim());
cmd.ExecuteNonQuery();
//TRANSFER tables
cmd.CommandText = "SELECT DISTINCT detail.DocumentNumber " +
"FROM InventoryTransfer_Detail detail " +
"INNER JOIN InventoryTransfer_Serial serial ON detail.DocumentNumber = serial.DocumentNumber " +
"and detail.ItemNumber = serial.ItemNumber " +
"and detail.LineSequenceNumber = serial.LineSequenceNumber " +
"WHERE SessionID = " + SqlString(dr["SessionID"].ToString().Trim()) +
" and SerialNumber = " + SqlString(dr["SerialNumber"].ToString().Trim());
object obj = cmd.ExecuteScalar();
if (obj != null)
{
cmd.CommandText = "UPDATE InventoryTransfer_Master " +
"SET Completed = 0 WHERE DocumentNumber = " + SqlString(obj.ToString());
cmd.ExecuteNonQuery();
cmd.CommandText = "UPDATE InventoryTransfer_Serial " +
"SET OriginalBin = '', NewBin = '' " +
"WHERE DocumentNumber = " + SqlString(obj.ToString()) + " and SerialNumber = " + SqlString(dr["SerialNumber"].ToString().Trim());
cmd.ExecuteNonQuery();
}
}
}
if (conn.State == ConnectionState.Open)
conn.Close();
}
//this.Close();
}
catch (Exception ex)
{
ELog el = new ELog(ex, CLASS_NAME + " revertSave");
}
}
答案 0 :(得分:3)
如果没有实际尝试复杂系统,很难预测复杂系统的性能,但存储过程很可能会提高执行速度,尤其是在数据集很大的情况下。
使用您当前的方法
使用存储过程,理论上可以
使用存储过程看起来好一点,除了可能更大的锁定。根据您的整体解决方案,该锁定可能是一个交易破坏者,因为它可能会阻止其他用户尝试同时执行相同操作。
还有一些恶魔般的细节 - 例如,一次更新一行可能比进行大规模更新更有效,如果表格很大且有许多行没有更新,并且批量更新触发表扫描而不是索引搜索。但是,一个优秀的SQL开发人员可以定制SQL查询和命令,以便在正确的方向上轻推SQL Server。
TLDR:在大多数情况下,存储过程会为您提供更好的性能。
答案 1 :(得分:2)
正如其他人所说,SQL注入和事务都是问题。此代码的其他潜在问题是可维护性(易于键入和易于查找以及易于调试)。任何这些问题都可能比性能更重要。看起来它可能比基于集合的逻辑做更多的基于行的逻辑,这通常是一个性能问题。如果在公司中习惯于在代码中构建SQL,并且这在一段时间内运行,这对系统或运行它的人来说并不繁琐,那么它可能是最好的地方(抛开它的威胁) SQL注入)。
如果这会导致实际性能问题,则应对其进行优化,优化的最佳方法是进行测试。它以这种方式在5分钟内运行吗?当你将它转换为存储过程时,需要1分钟吗?当你删除循环并使其完全基于集合的逻辑时怎么样?