2012-02-23 23 views
6

Mam pytanie dotyczące efektywnego sposobu aktualizowania wielu wierszy za pomocą SQL.C#, aktualizacja SQL wielu wierszy

basiclly Mam kwerendy trzeba uruchomić na różnych RowIDs:

UPDATE TableName SET Column = (some number) WHERE RowID = (some number) 

gdyby dokładniej jest to lepszy przykład:

UPDATE TableName SET Column = 5 WHERE RowID = 1000 
UPDATE TableName SET Column = 10 WHERE RowID = 1001 
UPDATE TableName SET Column = 30 WHERE RowID = 1002 
.. 

Chciałbym wiedzieć, w jaki sposób należy buduję polecenie zapytania aktualizacji w języku C# (lub po prostu podam przykład kwerendy wynikowej, do której powinienem się dostać), więc gdy tylko użyję ExecuteQuery, uruchomię wszystkie te polecenia w jednym kawałku, a nie wykonując każde polecenie.

edycja: mam inny problem, można również wyjaśnić, co o dynamicznej sytuacji, w której nie necessarly wiersz Chcę zaktualizować istnieje już w tym przypadku muszę wstawić zamiast aktualizacji. aby lepiej wyjaśnić, z powrotem do mojego przykładu powiedzmy, że chcę zrobić

UPDATE TableName SET Column = 5 WHERE RowID = 1000 
INSERT INTO TableName [RowID, Column] VALUES (1001, 20) 
UPDATE TableName SET Column = 30 WHERE RowID = 1002 
.. 

rozumieniu jest to, że trzeba sprawdzić, jeśli wiersz istnieje, jeżeli tak użyję aktualizacji inaczej będę musiał wstawić to.

Dziękujemy!

+0

Procedura przechowywana? – Vedran

+0

Czy możesz potwierdzić, którego produktu bazy danych i wersji używasz? Dla nowoczesnego SQL Server (> = 2008), będziesz szukał używania parametru o wartości tabelarycznej i instrukcji 'MERGE' –

Odpowiedz

7

Można użyć DataTable do przechowywania ewidencji, wstawić, usunąć lub zmienić wiersze i aktualizuje wszystkie zmiany w jednej partii przy użyciu SqlDataAdapter na UpdateBatchSize (0 oznacza brak limitu):

public static void BatchUpdate(DataTable dataTable,Int32 batchSize) 
{ 
    // Assumes GetConnectionString() returns a valid connection string. 
    string connectionString = GetConnectionString(); 

    // Connect to the AdventureWorks database. 
    using (SqlConnection connection = new 
     SqlConnection(connectionString)) 
    { 

     // Create a SqlDataAdapter. 
     SqlDataAdapter adapter = new SqlDataAdapter(); 

     // Set the UPDATE command and parameters. 
     adapter.UpdateCommand = new SqlCommand(
      "UPDATE Production.ProductCategory SET " 
      + "[email protected] WHERE [email protected];", 
      connection); 
     adapter.UpdateCommand.Parameters.Add("@Name", 
      SqlDbType.NVarChar, 50, "Name"); 
     adapter.UpdateCommand.Parameters.Add("@ProdCatID", 
      SqlDbType.Int, 4, "ProductCategoryID"); 
     adapter.UpdateCommand.UpdatedRowSource = UpdateRowSource.None; 

     // Set the INSERT command and parameter. 
     adapter.InsertCommand = new SqlCommand(
      "INSERT INTO Production.ProductCategory (Name) VALUES (@Name);", 
      connection); 
     adapter.InsertCommand.Parameters.Add("@Name", 
      SqlDbType.NVarChar, 50, "Name"); 
     adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.None; 

     // Set the DELETE command and parameter. 
     adapter.DeleteCommand = new SqlCommand(
      "DELETE FROM Production.ProductCategory " 
      + "WHERE [email protected];", connection); 
     adapter.DeleteCommand.Parameters.Add("@ProdCatID", 
      SqlDbType.Int, 4, "ProductCategoryID"); 
     adapter.DeleteCommand.UpdatedRowSource = UpdateRowSource.None; 

     // Set the batch size. 
     adapter.UpdateBatchSize = batchSize; 

     // Execute the update. 
     adapter.Update(dataTable); 
    } 
} 

http://msdn.microsoft.com/en-us/library/aadf8fk2.aspx

Zakładam, że nie rozumiesz, w jaki sposób DBMS działa wewnętrznie. Ten

UPDATE TableName SET Column = 5 WHERE RowID = 1000; 
UPDATE TableName SET Column = 5 WHERE RowID = 1002; 

jest taka sama jak

UPDATE TableName SET Column = 5 WHERE RowID IN(1000,2002); 

DBMS aktualizuje wszystkie rekordy poszkodowanym jeden po drugim i tak nawet jeśli byś napisać oświadczenie jak UPDATE table SET value=1 które mogłyby mieć wpływ na każdy rekord w tabeli. Aktualizując jedną partię, upewniasz się, że wszystkie aktualizacje (usuwa, wstawia) są przesyłane do bazy danych zamiast jednego obiegu za każdą instrukcję.

+0

Przeglądam kod aktualizacji (ponieważ jest on najbardziej odpowiedni dla mojego pytania), a ja nie dość rozumiem, co jest wynikowym zapytaniem na końcu i dlaczego jest wydajne? wygląda na to, że budujesz zapytanie, którego próbuję uniknąć, prawda? – Popokoko

+1

System dbms aktualizuje wszystkie uszkodzone rekordy jeden po drugim, nawet jeśli napiszesz instrukcję typu 'UPDATE table SET value = 1', która wpłynie na każdy rekord w tabeli.Aktualizując w jednej partii, upewniasz się, że wszystkie aktualizacje (usuwa, wstawia) są jednocześnie zatwierdzane w tej samej transakcji. –

+0

Należy zauważyć, że 'Update (dataTable)' jest [udokumentowane] (http://msdn.microsoft.com/en-us/library/z1z2bkx2.aspx), aby nie grupować aktualizacji: "Należy zauważyć, że te instrukcje nie są wykonywane jako proces wsadowy, każdy wiersz jest aktualizowany indywidualnie. ", a partie i transakcje są dwiema prostymi koncepcjami w SQL. –

0

Zastosowanie MERGE:

MERGE INTO TableName 
    USING (
      VALUES (1000, 5), 
       (1001, 10), 
       (1002, 30) 
     ) AS source (RowID, Column_name) 
     ON TableName.RowID = source.RowID 
WHEN MATCHED THEN 
    UPDATE 
     SET Column_name = source.Column_name 
WHEN NOT MATCHED THEN 
    INSERT (RowID, Column_name) 
     VALUES (RowID, Column_name); 

Zamiast twardych kodowania/dynamiczny SQL, oświadczenie MERGE można zamykać w przechowywanej obrady że bierze table-valued parameter.

Powiązane problemy