2012-02-23 44 views
6

tôi có một câu hỏi liên quan đến một cách hiệu quả để cập nhật nhiều hàng thông qua SQL.C#, SQL cập nhật nhiều hàng

basiclly tôi có một câu hỏi tôi cần phải chạy trên RowIDs khác nhau:

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

nếu để cụ thể hơn đây là một ví dụ tốt hơn:

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

Tôi muốn biết làm thế nào nên i xây dựng lệnh truy vấn cập nhật trên C# (hoặc chỉ cho tôi một ví dụ về truy vấn kết quả mà tôi sẽ nhận được) vì vậy khi tôi sử dụng ExecuteQuery nó sẽ chạy tất cả các lệnh này tại một phần và không phải bằng cách thực thi mỗi lệnh.

chỉnh sửa: Tôi có một vấn đề khác, có thể bạn cũng giải thích những gì về tình hình năng động trong đó không necessarly hàng tôi muốn cập nhật tồn tại đã có, trong trường hợp mà tôi cần phải chèn thay vì cập nhật. để giải thích tốt hơn, trở lại ví dụ của tôi cho phép nói rằng tôi muốn làm

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

Ý nghĩa của việc này là tôi cần phải kiểm tra xem hàng tồn tại, nếu vì vậy tôi muốn sử dụng bản cập nhật nếu không tôi sẽ phải chèn nó.

Cảm ơn bạn!

+0

Quy trình được lưu trữ? – Vedran

+0

Bạn có thể xác nhận sản phẩm và phiên bản cơ sở dữ liệu nào bạn đang sử dụng không? Đối với SQL Server hiện đại (> = 2008), bạn sẽ xem xét sử dụng tham số có giá trị bảng và câu lệnh 'MERGE' –

Trả lời

7

Bạn có thể sử dụng một DataTable để lưu trữ hồ sơ của bạn, chèn, xóa hay thay đổi hàng và cập nhật tất cả những thay đổi trong cùng một nhóm bằng cách sử dụng SqlDataAdapter của UpdateBatchSize (0 có nghĩa là không có giới hạn):

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

Tôi cho rằng bạn hiểu sai về cách các dbms hoạt động trong nội bộ. Đây

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

cũng giống như

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

Các DBMS sẽ cập nhật tất cả hồ sơ bị ảnh hưởng từng cái một nào ngay cả khi bạn sẽ viết một tuyên bố như UPDATE table SET value=1 đó sẽ ảnh hưởng đến mọi kỷ lục trong bảng. Bằng cách cập nhật trong một lô, bạn đảm bảo rằng tất cả các bản cập nhật (xóa, chèn) được gửi đến cơ sở dữ liệu thay vì một vòng lặp cho mỗi câu lệnh.

+0

Tôi đang xem mã cập nhật (vì nó có liên quan nhất đến câu hỏi của tôi) và tôi không khá hiểu kết quả truy vấn cuối cùng là gì và tại sao nó lại hiệu quả? có vẻ như bạn đang xây dựng truy vấn cố gắng tránh phải không? – Popokoko

+1

Các dbms sẽ cập nhật tất cả các hồ sơ bị ảnh hưởng từng người một anyway ngay cả khi bạn sẽ viết một tuyên bố như 'UPDATE bảng SET giá trị = 1' mà sẽ ảnh hưởng đến mọi bản ghi trong bảng.Bằng cách cập nhật trong một lô, bạn đảm bảo rằng tất cả các cập nhật (xóa, chèn) được cam kết cùng một lúc trong cùng một giao dịch. –

+0

Cần lưu ý rằng 'Cập nhật (dataTable)' là [tài liệu] (http://msdn.microsoft.com/en-us/library/z1z2bkx2.aspx) không để lô cập nhật: "Cần lưu ý rằng những các câu lệnh không được thực hiện như một tiến trình lô; mỗi hàng được cập nhật riêng lẻ. ", và các lô và giao dịch đó là hai khái niệm trực giao trong SQL. –

0

Sử dụng 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); 

Thay vì cứng mã hóa/SQL động, báo cáo kết quả MERGE có thể được gói gọn vào một proc lưu trữ mà phải mất một table-valued parameter.

Các vấn đề liên quan