我用三个sql查询编写了以下方法,以便更新单个表中的单个列。因为有近10000条记录需要更新,所以需要20多分钟才能完成。还有其他更好的方法吗这个更新。有点像基于集合的更新......
private void UpdateLatest()
{
string connstr = "Data Source=CHAMARA-PC;Initial Catalog=PHPA_Production_fromEWP;Integrated Security=True";
using (SqlConnection conn = new SqlConnection(connstr))
{
conn.Open();
SqlTransaction myTransaction = conn.BeginTransaction();
try
{
DataTable dt = new DataTable();
DataTable DTT = new DataTable();
string command = "select dh.DocumentNumber,max(dr.RevisionDate) as latestdate from " +
"tblDocumentHeader dh inner join tblDocumentRevision dr on dh.DocumentHeaderID=dr.DocumentHeaderID " +
"group by dh.DocumentNumber ";
using (SqlCommand cmd = new SqlCommand(command, conn, myTransaction))
{
using (SqlDataAdapter adapt = new SqlDataAdapter())
{
adapt.SelectCommand = cmd;
adapt.Fill(dt);
}
}
label1.Text = dt.Rows.Count.ToString();
foreach (DataRow item in dt.Rows)
{
try
{
int res = 0;
string query2 = "select dr.DocumentRevisionID from " +
"tblDocumentHeader dh inner join tblDocumentRevision dr on dh.DocumentHeaderID=dr.DocumentHeaderID " +
" where dh.DocumentNumber='" + item["DocumentNumber"].ToString().Trim() + "' and dr.RevisionDate='" + item["latestdate"].ToString().Trim() + "'";
using (SqlCommand cmd = new SqlCommand(query2, conn, myTransaction))
{
using (SqlDataAdapter adapt = new SqlDataAdapter())
{
adapt.SelectCommand = cmd;
adapt.Fill(DTT);
}
}
foreach (DataRow Ritem in DTT.Rows)
{
string updatequery = "update tblDocumentRevision set LatestRev='latest' where DocumentRevisionID='" + Ritem["DocumentRevisionID"].ToString().Trim() + "'";
using (SqlCommand cmd = new SqlCommand(updatequery, conn, myTransaction))
{
cmd.ExecuteNonQuery();
res++;
}
}
listBox1.Items.Add(item["DocumentNumber"].ToString() + " " + "updated");
}
catch (Exception ex)
{
throw ex;
}
}
myTransaction.Commit();
MessageBox.Show("successfully updated");
}
catch (Exception ex)
{
myTransaction.Rollback();
MessageBox.Show(ex.Message);
}
}
}
答案 0 :(得分:3)
我手边没有你的数据库来测试这个,但基本上,你的代码归结为:
DECLARE @Temp TABLE (DocNumber INT, LatestDate DATETIME)
INSERT INTO @Temp(DocNumber, LatestDate)
SELECT
dh.DocumentNumber, MAX(dr.RevisionDate)
FROM
dbo.tblDocumentHeader dh
INNER JOIN
dbo.tblDocumentRevision dr ON dh.DocumentHeaderID = dr.DocumentHeaderID
GROUP BY
dh.DocumentNumber
UPDATE
dbo.tblDocumentRevision
SET
LatestRev = 'latest'
FROM
dbo.tblDocumentRevision dr
INNER JOIN
dbo.tblDocumentHeader dh ON dh.DocumentHeaderID = dr.DocumentHeaderID
INNER JOIN
@Temp t ON dh.DocumentNumber = t.DocNumber AND dr.RevisionDate = t.LatestDate
这可以很容易地包装在存储过程中,不使用任何死慢游标,并且不导致任何SQL注入可能性。
答案 1 :(得分:2)
因为有近10000条记录需要更新,所以需要20多分钟才能完成
学习SQL。
好的,首先 - 10.000更新语句= 20分钟表示您的服务器是带有慢速光盘的笔记本电脑,而不是数据库服务器。这太长了。你做的方式是可怕的慢,但最后...... 20分钟太慢了。如果这是一个真正的数据库 - 为它获取服务器。您每秒执行的更新少于10次,即使普通桌面也可以处理大约75次。
现在:
您选择然后更新。为什么?为什么不
更新tblDocumentRevision设置LatestRev ='latest',其中DocumentRevisionID IN(x,y,z)
并且每100个左右的文件开一次?这粗暴地减少了你发表的声明数量。
如果那个母猪过于播种,你应该将它们从异步中激活 - 在语句1执行时准备语句2,或者甚至并行地从多个工作线程中激活它们。
最后,SQL基础知识:DocumentRevisionID上有索引吗? 第三,这里不需要使用适配器和dta表。这是一种笨拙,笨拙,通常会避免正确的编程习惯。