此 C#/sql 查询代码需要花费大量时间来更新 table
This C# / sql query code takes a lot of time to update the table
任何人都可以帮助提高性能吗?更新 table 需要很多时间。
我正在将序列号从 datagridview 更新到名为 dbo.json
的 table
// UPDATE dbo.json with numbers
private void BtnUpdateSql_Click(object sender, EventArgs e)
{
string VAL1;
string VAL2;
foreach (DataGridViewRow row in DgvWhistlSorted.Rows)
if (string.IsNullOrEmpty(row.Cells[5].Value as string))
{
}
else
{
for (int i = 0; i <= DgvWhistlSorted.Rows.Count - 2; i++)
{
VAL1 = DgvWhistlSorted.Rows[i].Cells[6].Value.ToString();
VAL2 = DgvWhistlSorted.Rows[i].Cells[0].Value.ToString();
var cnn = ConfigurationManager.ConnectionStrings["sql"].ConnectionString;
using (var con = new SqlConnection(cnn))
{
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "UPDATE dbo.json SET RowN = @VAL1 WHERE [A-order] = @VAL2";
cmd.Parameters.AddWithValue("@VAL1", VAL1);
cmd.Parameters.AddWithValue("@VAL2", VAL2);
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
}
MessageBox.Show("dbo.json is ready");
}
您不应该在如此紧密的循环中创建连接和命令 - 在循环之前创建并打开连接和命令 ONCE,在循环中,仅设置参数值并为每个条目执行查询。
像这样:
// UPDATE dbo.json with numbers
private void BtnUpdateSql_Click(object sender, EventArgs e)
{
string VAL1;
string VAL2;
// define connection string, query text *ONCE* before the loop
string cnn = ConfigurationManager.ConnectionStrings["sql"].ConnectionString;
string updateQuery = "UPDATE dbo.json SET RowN = @VAL1 WHERE [A-order] = @VAL2;";
// create connection and command *ONCE*
using (SqlConnection con = new SqlConnection(cnn))
using (SqlCommand cmd = new SqlCommand(updateQuery, cnn))
{
// Define parameters - adapt as needed (don't know the actual datatype they have)
cmd.Parameters.Add("@VAL1", SqlDbType.VarChar, 100);
cmd.Parameters.Add("@VAL2", SqlDbType.VarChar, 100);
// open connection ONCE, for all updates
con.Open();
foreach (DataGridViewRow row in DgvWhistlSorted.Rows)
{
if (!string.IsNullOrEmpty(row.Cells[5].Value as string))
{
for (int i = 0; i <= DgvWhistlSorted.Rows.Count - 2; i++)
{
VAL1 = DgvWhistlSorted.Rows[i].Cells[6].Value.ToString();
VAL2 = DgvWhistlSorted.Rows[i].Cells[0].Value.ToString();
// set the values
cmd.Parameters["@VAL1"].Value = VAL1;
cmd.Parameters["@VAL2"].Value = VAL2;
// execute query
cmd.ExecuteNonQuery();
}
}
}
// close connection after all updates are done
con.Close();
}
MessageBox.Show("dbo.json is ready");
}
一个更好的想法是在一个命令中完成,通过在 Table-Value 参数 (TVP):
中传递所有数据
首先创建table类型。我不知道你的数据类型,所以我在这里猜测。确保将类型与现有的 table.
相匹配
CREATE TYPE dbo.OrderJson (
Order int PRIMARY KEY,
RowN nvarchar(max) NOT NULL
);
那你就可以一次性全部通过了。您需要创建一个 DataTable
作为参数传递,或者您可以使用现有数据 table.
// UPDATE dbo.json with numbers
private void BtnUpdateSql_Click(object sender, EventArgs e)
{
var table = new DataTable {
Columns = {
{ "Order", typeof(int) },
{ "RowN", typeof(string) },
},
};
foreach (DataGridViewRow row in DgvWhistlSorted.Rows)
if (!string.IsNullOrEmpty(row.Cells[5].Value as string))
table.Rows.Add(DgvWhistlSorted.Rows[i].Cells[0].Value, DgvWhistlSorted.Rows[i].Cells[6].Value)
const string query = @"
UPDATE dbo.json
SET RowN = t.RowN
FROM dbo.json j
JOIN @tmp t ON t.order = j.[A-order];
";
using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["sql"].ConnectionString))
using (var cmd = new SqlCommand(query, con))
{
cmd.Parameters.Add(new SqlParameter("@tmp", SqlDbType.Structured) { Value = table, TypeName = "dbo.OrderJson" });
con.Open();
cmd.ExecuteNonQuery();
}
MessageBox.Show("dbo.json is ready");
}
创建一次连接...您每次都在通过循环创建一个新的数据库连接!事实上,您不需要每次都创建新的命令对象。您可以重用命令对象,因为参数是相同的。每次通过循环清除参数即可。
也不要在循环中进行网格视图计数,为其设置一个变量。
string query = "UPDATE dbo.json SET RowN = @VAL1 WHERE [A-order] = @VAL2";
int counter = DgvWhistlSorted.Rows.Count - 2;
using (SqlConnection con = new SqlConnection(cnn))
{
con.Open();
using(SqlCommand cmd = new SqlCommand(cnn,query))
{
cmd.Parameters.Clear();
//Do your loop in here
for (int i = 0; i <= counter; i++)
{
VAL1 = DgvWhistlSorted.Rows[i].Cells[6].Value.ToString();
VAL2 = DgvWhistlSorted.Rows[i].Cells[0].Value.ToString();
cmd.Parameters.AddWithValue("@VAL1", VAL1);
cmd.Parameters.AddWithValue("@VAL2", VAL2);
cmd.ExecuteNonQuery();
}
}
}
我发现最快的方法是将 DATAGRIDVIEW 保存到 SQL table 并使用 - 存储过程 + 更新查询 - 在两个 table 之间继续这个过程 -现在它飞...
谢谢大家
任何人都可以帮助提高性能吗?更新 table 需要很多时间。
我正在将序列号从 datagridview 更新到名为 dbo.json
的 table// UPDATE dbo.json with numbers
private void BtnUpdateSql_Click(object sender, EventArgs e)
{
string VAL1;
string VAL2;
foreach (DataGridViewRow row in DgvWhistlSorted.Rows)
if (string.IsNullOrEmpty(row.Cells[5].Value as string))
{
}
else
{
for (int i = 0; i <= DgvWhistlSorted.Rows.Count - 2; i++)
{
VAL1 = DgvWhistlSorted.Rows[i].Cells[6].Value.ToString();
VAL2 = DgvWhistlSorted.Rows[i].Cells[0].Value.ToString();
var cnn = ConfigurationManager.ConnectionStrings["sql"].ConnectionString;
using (var con = new SqlConnection(cnn))
{
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "UPDATE dbo.json SET RowN = @VAL1 WHERE [A-order] = @VAL2";
cmd.Parameters.AddWithValue("@VAL1", VAL1);
cmd.Parameters.AddWithValue("@VAL2", VAL2);
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
}
MessageBox.Show("dbo.json is ready");
}
您不应该在如此紧密的循环中创建连接和命令 - 在循环之前创建并打开连接和命令 ONCE,在循环中,仅设置参数值并为每个条目执行查询。
像这样:
// UPDATE dbo.json with numbers
private void BtnUpdateSql_Click(object sender, EventArgs e)
{
string VAL1;
string VAL2;
// define connection string, query text *ONCE* before the loop
string cnn = ConfigurationManager.ConnectionStrings["sql"].ConnectionString;
string updateQuery = "UPDATE dbo.json SET RowN = @VAL1 WHERE [A-order] = @VAL2;";
// create connection and command *ONCE*
using (SqlConnection con = new SqlConnection(cnn))
using (SqlCommand cmd = new SqlCommand(updateQuery, cnn))
{
// Define parameters - adapt as needed (don't know the actual datatype they have)
cmd.Parameters.Add("@VAL1", SqlDbType.VarChar, 100);
cmd.Parameters.Add("@VAL2", SqlDbType.VarChar, 100);
// open connection ONCE, for all updates
con.Open();
foreach (DataGridViewRow row in DgvWhistlSorted.Rows)
{
if (!string.IsNullOrEmpty(row.Cells[5].Value as string))
{
for (int i = 0; i <= DgvWhistlSorted.Rows.Count - 2; i++)
{
VAL1 = DgvWhistlSorted.Rows[i].Cells[6].Value.ToString();
VAL2 = DgvWhistlSorted.Rows[i].Cells[0].Value.ToString();
// set the values
cmd.Parameters["@VAL1"].Value = VAL1;
cmd.Parameters["@VAL2"].Value = VAL2;
// execute query
cmd.ExecuteNonQuery();
}
}
}
// close connection after all updates are done
con.Close();
}
MessageBox.Show("dbo.json is ready");
}
一个更好的想法是在一个命令中完成,通过在 Table-Value 参数 (TVP):
中传递所有数据首先创建table类型。我不知道你的数据类型,所以我在这里猜测。确保将类型与现有的 table.
相匹配CREATE TYPE dbo.OrderJson (
Order int PRIMARY KEY,
RowN nvarchar(max) NOT NULL
);
那你就可以一次性全部通过了。您需要创建一个 DataTable
作为参数传递,或者您可以使用现有数据 table.
// UPDATE dbo.json with numbers
private void BtnUpdateSql_Click(object sender, EventArgs e)
{
var table = new DataTable {
Columns = {
{ "Order", typeof(int) },
{ "RowN", typeof(string) },
},
};
foreach (DataGridViewRow row in DgvWhistlSorted.Rows)
if (!string.IsNullOrEmpty(row.Cells[5].Value as string))
table.Rows.Add(DgvWhistlSorted.Rows[i].Cells[0].Value, DgvWhistlSorted.Rows[i].Cells[6].Value)
const string query = @"
UPDATE dbo.json
SET RowN = t.RowN
FROM dbo.json j
JOIN @tmp t ON t.order = j.[A-order];
";
using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["sql"].ConnectionString))
using (var cmd = new SqlCommand(query, con))
{
cmd.Parameters.Add(new SqlParameter("@tmp", SqlDbType.Structured) { Value = table, TypeName = "dbo.OrderJson" });
con.Open();
cmd.ExecuteNonQuery();
}
MessageBox.Show("dbo.json is ready");
}
创建一次连接...您每次都在通过循环创建一个新的数据库连接!事实上,您不需要每次都创建新的命令对象。您可以重用命令对象,因为参数是相同的。每次通过循环清除参数即可。
也不要在循环中进行网格视图计数,为其设置一个变量。
string query = "UPDATE dbo.json SET RowN = @VAL1 WHERE [A-order] = @VAL2";
int counter = DgvWhistlSorted.Rows.Count - 2;
using (SqlConnection con = new SqlConnection(cnn))
{
con.Open();
using(SqlCommand cmd = new SqlCommand(cnn,query))
{
cmd.Parameters.Clear();
//Do your loop in here
for (int i = 0; i <= counter; i++)
{
VAL1 = DgvWhistlSorted.Rows[i].Cells[6].Value.ToString();
VAL2 = DgvWhistlSorted.Rows[i].Cells[0].Value.ToString();
cmd.Parameters.AddWithValue("@VAL1", VAL1);
cmd.Parameters.AddWithValue("@VAL2", VAL2);
cmd.ExecuteNonQuery();
}
}
}
我发现最快的方法是将 DATAGRIDVIEW 保存到 SQL table 并使用 - 存储过程 + 更新查询 - 在两个 table 之间继续这个过程 -现在它飞... 谢谢大家