2015-09-29 86 views
0

鑑於我們在下表中有:什麼是最好的方式插入/更新的數據到數據庫

CREATE TABLE TestData 
(
    ID INT NOT NULL PRIMARY KEY, 
    Value INT 
) 

當寫入數據表中,我會盡量UPDATE表,如果ID已經存在或否則INSERT一個新的行。

有我寫或在生產代碼遇到幾個選項:

  1. 首先執行UPDATE查詢,如果沒有行被更新,執行INSERT查詢

  2. 執行Insert查詢首先第一,如果失敗,執行INSERT查詢

  3. 第一執行SELECT查詢與新的ID ,那麼如果該行存在做UPDATE其他INSERT查詢

  4. 執行一個大的查詢做的所有選擇更新或插入

我的問題是什麼是best practicemost efficientpreferred method之中上述選項(或你自己的方法)?

對於上述選項的示例代碼:

(1)首先執行UPDATE查詢,如果沒有行被更新,執行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) { /*...*/ } 
    } 
} 

(2)第一首先執行Insert查詢,如果失敗,執行INSERT查詢

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) { /*...*/ } 
    } 
} 

(3)執行SELECT曲ERY新的ID,然後再如果行存在做UPDATE其他INSERT查詢

bool dataExist = false; 
// ... 
using (IDbCommand selectCmd = new SqlCommand("SELECT ID FROM TestDate WHERE [email protected]", 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 [email protected]) " + 
       "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) { /*...*/ } 
} 
+0

檢查您是否可以使用'MERGE' – lad2025

+1

對我而言..因爲你的代碼非常容易發生SQL注入!如果你用它來克服,那麼你可以創建一個存儲過程並創建你的更新並在其中插入邏輯。 –

+0

@ lad2025這是一個直接插入表中的新數據。我應該從哪裏'合併'? –

回答

0

你可以使用MERGE

對目標表執行基於 的對源表的連接結果的插入,更新或刪除操作。

對於併發原因,是更好的使用MERGEIF EXISTS/UPDATE/INSERT而且只有一個語句,因此維護更少的代碼:

喜歡的東西:

SqlFiddleDemo

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; 
+0

這是一個大的查詢從C#調用? –

+0

是的,你需要綁定參數,它應該工作。但首先檢查使用SSMS – lad2025

+0

@VietNguyen看演示 – lad2025

相關問題