C# 向数据库插入/更新数据的最佳方式是什么
鉴于我们有下表:C# 向数据库插入/更新数据的最佳方式是什么,c#,sql,database,performance,C#,Sql,Database,Performance,鉴于我们有下表: CREATE TABLE TestData ( ID INT NOT NULL PRIMARY KEY, Value INT ) 在将数据写入表时,如果ID已经存在,我将尝试更新表,或者插入一个新行 我在生产代码中编写或遇到了几个选项: 首先执行更新查询,如果没有更新行,则执行插入查询 int affectedRows = 0; using (IDbCommand updateCmd = new SqlCommand("UPDATE TestData SET
CREATE TABLE TestData
(
ID INT NOT NULL PRIMARY KEY,
Value INT
)
在将数据写入表时,如果ID已经存在,我将尝试更新表,或者插入一个新行
我在生产代码中编写或遇到了几个选项:
首先执行更新
查询,如果没有更新行,则执行插入
查询
int affectedRows = 0;
using (IDbCommand updateCmd = new SqlCommand("UPDATE TestData SET Value = @Value WHERE ID = @ID", myConn))
{
try
{
// ...add params
affectedRows = updateCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
if (affectedRows == 0)
{
using (IDbCommand insertCmd = new SqlCommand("INSERT INTO TestData VALUES (@ID, @Value)", myConn))
{
try
{
// ...add params
affectedRows = insertCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
}
int affectedRows = 0;
using (IDbCommand insertCmd = new SqlCommand("INSERT INTO TestData VALUES (@ID, @Value)", myConn))
{
try
{
// ... add params
affectedRows = insertCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
if (affectedRows == 0)
{
using (IDbCommand updateCmd = new SqlCommand("UPDATE TestData SET Value = @Value WHERE ID = @ID", myConn))
{
try
{
// ...add params
affectedRows = updateCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
}
bool dataExist = false;
// ...
using (IDbCommand selectCmd = new SqlCommand("SELECT ID FROM TestDate WHERE ID=@ID", myConn))
{
try
{
// ... add param
using (IDataReader reader = selectCmd.ExecuteReader())
dataExist = reader.Read();
}
catch (SqlException) { /*...*/ }
}
if (dataExist) { /* update query, similar to above one*/ }
else { /* insert, similar to above one */ }
首先执行Insert
查询,如果失败,则执行Insert
查询
int affectedRows = 0;
using (IDbCommand updateCmd = new SqlCommand("UPDATE TestData SET Value = @Value WHERE ID = @ID", myConn))
{
try
{
// ...add params
affectedRows = updateCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
if (affectedRows == 0)
{
using (IDbCommand insertCmd = new SqlCommand("INSERT INTO TestData VALUES (@ID, @Value)", myConn))
{
try
{
// ...add params
affectedRows = insertCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
}
int affectedRows = 0;
using (IDbCommand insertCmd = new SqlCommand("INSERT INTO TestData VALUES (@ID, @Value)", myConn))
{
try
{
// ... add params
affectedRows = insertCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
if (affectedRows == 0)
{
using (IDbCommand updateCmd = new SqlCommand("UPDATE TestData SET Value = @Value WHERE ID = @ID", myConn))
{
try
{
// ...add params
affectedRows = updateCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
}
bool dataExist = false;
// ...
using (IDbCommand selectCmd = new SqlCommand("SELECT ID FROM TestDate WHERE ID=@ID", myConn))
{
try
{
// ... add param
using (IDataReader reader = selectCmd.ExecuteReader())
dataExist = reader.Read();
}
catch (SqlException) { /*...*/ }
}
if (dataExist) { /* update query, similar to above one*/ }
else { /* insert, similar to above one */ }
首先使用新ID执行选择
查询,然后如果行存在,则执行更新
其他插入
查询
int affectedRows = 0;
using (IDbCommand updateCmd = new SqlCommand("UPDATE TestData SET Value = @Value WHERE ID = @ID", myConn))
{
try
{
// ...add params
affectedRows = updateCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
if (affectedRows == 0)
{
using (IDbCommand insertCmd = new SqlCommand("INSERT INTO TestData VALUES (@ID, @Value)", myConn))
{
try
{
// ...add params
affectedRows = insertCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
}
int affectedRows = 0;
using (IDbCommand insertCmd = new SqlCommand("INSERT INTO TestData VALUES (@ID, @Value)", myConn))
{
try
{
// ... add params
affectedRows = insertCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
if (affectedRows == 0)
{
using (IDbCommand updateCmd = new SqlCommand("UPDATE TestData SET Value = @Value WHERE ID = @ID", myConn))
{
try
{
// ...add params
affectedRows = updateCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
}
bool dataExist = false;
// ...
using (IDbCommand selectCmd = new SqlCommand("SELECT ID FROM TestDate WHERE ID=@ID", myConn))
{
try
{
// ... add param
using (IDataReader reader = selectCmd.ExecuteReader())
dataExist = reader.Read();
}
catch (SqlException) { /*...*/ }
}
if (dataExist) { /* update query, similar to above one*/ }
else { /* insert, similar to above one */ }
执行一个大查询以执行所有选择更新或插入操作
string query = "IF EXISTS (SELECT ID FROM TestData WHERE ID=@ID) " +
"UPDATE TestData SET Value = @Value WHERE ID = @ID " +
"ELSE INSERT INTO TestData VALUES (@ID, @Value)";
using (IDbCommand bigQueryCmd = new SqlCommand(query, myConn))
{
try
{
// ... add param
bigQueryCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
我的问题是,在上述选项(或您自己的方法)中,什么是最佳实践
或最有效的
或首选方法
上述选项的示例代码:
(1) 首先执行更新
查询,如果没有更新行,则执行插入
查询
int affectedRows = 0;
using (IDbCommand updateCmd = new SqlCommand("UPDATE TestData SET Value = @Value WHERE ID = @ID", myConn))
{
try
{
// ...add params
affectedRows = updateCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
if (affectedRows == 0)
{
using (IDbCommand insertCmd = new SqlCommand("INSERT INTO TestData VALUES (@ID, @Value)", myConn))
{
try
{
// ...add params
affectedRows = insertCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
}
int affectedRows = 0;
using (IDbCommand insertCmd = new SqlCommand("INSERT INTO TestData VALUES (@ID, @Value)", myConn))
{
try
{
// ... add params
affectedRows = insertCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
if (affectedRows == 0)
{
using (IDbCommand updateCmd = new SqlCommand("UPDATE TestData SET Value = @Value WHERE ID = @ID", myConn))
{
try
{
// ...add params
affectedRows = updateCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
}
bool dataExist = false;
// ...
using (IDbCommand selectCmd = new SqlCommand("SELECT ID FROM TestDate WHERE ID=@ID", myConn))
{
try
{
// ... add param
using (IDataReader reader = selectCmd.ExecuteReader())
dataExist = reader.Read();
}
catch (SqlException) { /*...*/ }
}
if (dataExist) { /* update query, similar to above one*/ }
else { /* insert, similar to above one */ }
(2) 首先执行Insert
查询,如果失败,则执行Insert
查询
int affectedRows = 0;
using (IDbCommand updateCmd = new SqlCommand("UPDATE TestData SET Value = @Value WHERE ID = @ID", myConn))
{
try
{
// ...add params
affectedRows = updateCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
if (affectedRows == 0)
{
using (IDbCommand insertCmd = new SqlCommand("INSERT INTO TestData VALUES (@ID, @Value)", myConn))
{
try
{
// ...add params
affectedRows = insertCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
}
int affectedRows = 0;
using (IDbCommand insertCmd = new SqlCommand("INSERT INTO TestData VALUES (@ID, @Value)", myConn))
{
try
{
// ... add params
affectedRows = insertCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
if (affectedRows == 0)
{
using (IDbCommand updateCmd = new SqlCommand("UPDATE TestData SET Value = @Value WHERE ID = @ID", myConn))
{
try
{
// ...add params
affectedRows = updateCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
}
bool dataExist = false;
// ...
using (IDbCommand selectCmd = new SqlCommand("SELECT ID FROM TestDate WHERE ID=@ID", myConn))
{
try
{
// ... add param
using (IDataReader reader = selectCmd.ExecuteReader())
dataExist = reader.Read();
}
catch (SqlException) { /*...*/ }
}
if (dataExist) { /* update query, similar to above one*/ }
else { /* insert, similar to above one */ }
(3) 首先使用新ID执行选择
查询,然后如果行存在,则执行更新
其他插入
查询
int affectedRows = 0;
using (IDbCommand updateCmd = new SqlCommand("UPDATE TestData SET Value = @Value WHERE ID = @ID", myConn))
{
try
{
// ...add params
affectedRows = updateCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
if (affectedRows == 0)
{
using (IDbCommand insertCmd = new SqlCommand("INSERT INTO TestData VALUES (@ID, @Value)", myConn))
{
try
{
// ...add params
affectedRows = insertCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
}
int affectedRows = 0;
using (IDbCommand insertCmd = new SqlCommand("INSERT INTO TestData VALUES (@ID, @Value)", myConn))
{
try
{
// ... add params
affectedRows = insertCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
if (affectedRows == 0)
{
using (IDbCommand updateCmd = new SqlCommand("UPDATE TestData SET Value = @Value WHERE ID = @ID", myConn))
{
try
{
// ...add params
affectedRows = updateCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
}
bool dataExist = false;
// ...
using (IDbCommand selectCmd = new SqlCommand("SELECT ID FROM TestDate WHERE ID=@ID", myConn))
{
try
{
// ... add param
using (IDataReader reader = selectCmd.ExecuteReader())
dataExist = reader.Read();
}
catch (SqlException) { /*...*/ }
}
if (dataExist) { /* update query, similar to above one*/ }
else { /* insert, similar to above one */ }
(4) 执行一个大查询以执行所有选择更新或插入操作
string query = "IF EXISTS (SELECT ID FROM TestData WHERE ID=@ID) " +
"UPDATE TestData SET Value = @Value WHERE ID = @ID " +
"ELSE INSERT INTO TestData VALUES (@ID, @Value)";
using (IDbCommand bigQueryCmd = new SqlCommand(query, myConn))
{
try
{
// ... add param
bigQueryCmd.ExecuteNonQuery();
}
catch (SqlException) { /*...*/ }
}
您可以使用
基于目标表对目标表执行插入、更新或删除操作
关于与源表联接的结果
出于并发原因,使用MERGE
比如果存在/UPDATE/INSERT
要好得多,而且它只是一条语句,因此需要维护的代码更少:
比如:
CREATE TABLE TestData (
ID INT NOT NULL PRIMARY KEY,
Value INT);
INSERT INTO TestData
VALUES (1,3);
DECLARE @id INT = 1, @value INT = 10; -- will update
--DECLARE @id INT = 2, @value INT = 10; -- will insert
;MERGE TestData AS TGT
USING (SELECT * FROM (SELECT @id AS ID, @value AS VALUE) AS t) AS SRC
ON TGT.ID = SRC.ID
WHEN MATCHED THEN
UPDATE SET Value = SRC.[VALUE]
WHEN NOT MATCHED THEN
INSERT (ID, [VALUE])
VALUES (SRC.ID, SRC.[VALUE]);
SELECT *
FROM TestData;
检查您是否可以为我使用MERGE
。没有,因为您的代码很容易被SQL注入!如果您克服了这个问题,那么您可以创建一个存储过程,并在其中创建更新和插入逻辑。这是一个直接向表中插入新数据的过程。我应该从哪里合并?与派生表合并这是从C#调用的一个大查询吗?是的,您需要绑定参数,它应该可以工作。但首先使用SSMSI检查是否知道合并会起作用,问题是它是否比其他方法更好。我发现它非常类似于第四个选项(如果存在/UPDATE/INSERT)@VietNguyen MERGE只是一条语句,使用隐式事务完成。如果您有并发应用程序,并且在存在/更新/插入时使用多部分,该怎么办。一个查询可以在另一个查询插入数据时检查是否存在