2011-06-20 20 views
7

W jaki sposób mogę uzyskać partię update/insert przy użyciu SQLCommand. Chciałem stworzyć SQLCommand tekst dynamicznie for pętli MyObject[] w C# z 10 SQLParameterAktualizacja wsadowa/wstawianie za pomocą polecenia SQLCommand w języku C#

w przypadku luzem insert, muszę sprawdzić dla każdego rekordu, który już istnieje lub nie. tj

if not Exists(select pkid from table1 where [email protected] and [email protected])

begin

insert.... 

end

Należy to zrobić z C# .no procedurze przechowywanej w db

+0

muszę zarówno w procedurach C# only.SQL nie dozwolonych zgodnie z wymogami – MayureshP

Odpowiedz

13
SqlCommand command = new SqlCommand(); 
// Set connection, etc. 
for(int i=0; i< items.length; i++) { 
    command.CommandText += string.Format("update mytable set [email protected]_id{0} where id = @id{0};", i); 
    command.Parameters.Add("@s_id" + i, items[i].SId); 
    command.Parameters.Add("@id" + i, items[i].Id); 
} 
command.ExecuteNonQuery(); 
+0

's_id = @ s_id {0}, gdzie id = @id {0}' To będzie działać – MayureshP

+0

tak będzie zastąpić wartości i. – Saurabh

+0

Ja wyjaśniłem pytanie, przejrzyj je – MayureshP

0

możesz wysyłać swoje wartości jako ciągi rozdzielane przecinkami jako parametry procedury składowanej, a następnie dzielić je przy użyciu funkcji sql Split().

spróbować

StringBuilder Par1 = new StringBuilder(""); 
    StringBuilder Par2 = new StringBuilder(""); 
    for (var i = 0; i < MyObject.Length; i++) 
    { 
     if (i > 0) 
     { 
      Par1.Append(","); 
      Par2.Append(","); 
     } 
     Par1.Append(MyObject[i].Prop1); 
     Par2.Append(MyObject[i].Prop2); 
    } 
    myCommand.Parameters.Add(new SqlParameter("@Par1", Par1.ToString())); 
    myCommand.Parameters.Add(new SqlParameter("@Par2", Par2.ToString())); 
    myCommand.CommandText = "MyStoredProcedure"; 
    myCommand.CommandType = System.Data.CommandType.StoredProcedure; 
    myCommand.ExecuteNonQuery(); 

procedura składowana będzie wyglądać następująco

CREATE Procedure MyStoredProcedure 
(
    @Par1 as varchar(max), 
    @Par2 as varchar(Max) 
) 
AS 
create table #AllValues 
( 
value1 varchar(50), 
value2 varchar(50) 
); 

create table #Par1s 
( 
id integer, 
data varchar(50) 
); 

create table #Par2s 
( 
id integer, 
data varchar(50) 
); 
insert into #Par1s select * from dbo.Split (@Par1,',') 
insert into #Par2s select * from dbo.Split (@Par2,',') 

Insert into #AllValues(value1,value2) 
Select #Par1s.data,#Par2s.data From #Par1s Inner Join #Par2s On #Par1s.ID = #Par2s.ID 


Insert into myTable(Col1,Col2) 
Select value1,value2 from #AllValues 

można przekazać dowolną liczbę paramters przy użyciu tego samego podejścia w Insert lub Update

+0

wszystko odbywa się w języku C#, procedura przechowywana nie jest dozwolona zgodnie z wymogami. – MayureshP

+0

Nie mogę zrozumieć Brak roli procedury składowanej, ale w każdym razie dlaczego nie używać 'Linq do sql' lub' Entity Framework', która jest bardziej wydajna niż pisanie 'instrukcji sql' w kodzie –

+0

Ten projekt na etapie konserwacji.Nie możemy zaimplementować w nim nowego (tylko poprawki) – MayureshP

6

Tylko do dołączania wszystkich CommandTexts do jednej dużej polecenia wsadowego nie jest tak przydatne, jak się wydaje.

Główną zaletą przygotowanych instrukcji w języku C# jest to, że obciążenie w bazie danych jest wykonywane podczas tworzenia polecenia. Nie, kiedy ją wykonasz [np. z ExecuteNonQuery() - która wykonuje polecenie tylko wtedy, gdy nie utworzono obiektu transakcji].

Aby tego uniknąć i utworzyć obciążenie w bazie danych tylko raz dla wszystkich wyciągów, znacznie lepiej jest utworzyć obiekt Transaction i zatwierdzić tę transakcję. Następnie wszystkie polecenia zostaną wykonane bez dodatkowego obciążenia bazy danych.

Byłoby to lepsze appoach:

// Try to create the Command as early as possible with a valid Connection object 
string commandString = "UPDATE Mytable SET [email protected]_id where id = @id;"; 
var command = new SqlCommand(commandString, connection); 

// Then define a Transaction object with your Connection 
var transaction = connection.BeginTransaction(); 
command.Transaction = transaction; 

// Now iterate through your array 
for(int i=0; i<array.Length; i++) 
{ 
    command.Parameters.Add("@s_id", SqlDbType.YourType).Value = items[i].SId; 
    command.Parameters.Add("@id", SqlDbType.YourType).Value = items[i].Id; 
    command.ExecuteNonQuery(); // Not executed at this point 
} 

// And now execute it with the possibility to rollback all commands when it fails 
try { transaction.Commit(); } // Here the execution is committed to the DB 
catch (Exception) 
{ 
    transaction.Rollback(); 
    throw; 
} 
+0

instrukcja sql w var zwany connectionString? wtf – Evilripper

+1

Zmieniłem nazwę "connectionString" w "commandString". To powinno być lepsze nazewnictwo, prawda? – FluepkeSchaeng

0

To jest moje szybkie rozwiązanie do testowania szybki wstawianie periodyczny transakcji.

 using (var conn = new SqlConnection(GetConnectionStringFromSecret(args))) 
     { 
      conn.Open(); 

      stopwatch.Start(); 
      long counter = 0; 
      var tran = conn.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted); 
      SqlCommand cmd = new SqlCommand("", conn, tran); 
      cmd.CommandType = System.Data.CommandType.Text; 
      int batch_param_counter = 0; 
      foreach (var chars_table in table_of_table_of_chars) 
      { 
       var key = string.Concat(chars_table);//get 1st param 
       var hash = BitConverter.ToString(hasher.ComputeHash(Encoding.UTF8.GetBytes(key))).Replace("-", "").ToLowerInvariant();//get 2nd param 

       cmd.CommandText += $"insert into hash_table([key], hash) values(@key{batch_param_counter}, @hash{batch_param_counter});{Environment.NewLine}"; 
       var param_key = new SqlParameter("@key" + batch_param_counter, System.Data.SqlDbType.VarChar, 20); 
       param_key.Value = key; 
       cmd.Parameters.Add(param_key); 
       var hash_key = new SqlParameter("@hash" + batch_param_counter, System.Data.SqlDbType.VarChar, 32); 
       hash_key.Value = hash; 
       cmd.Parameters.Add(hash_key); 
       batch_param_counter++; 

       if (counter % 200 == 0) 
       { 
        cmd.Prepare(); 
        cmd.ExecuteNonQuery(); 
        cmd.Dispose(); 
        cmd = new SqlCommand("", conn, tran); 
        cmd.CommandType = System.Data.CommandType.Text; 
        batch_param_counter = 0; 
       } 

       if (counter % 20000 == 0) 
       { 
        if (cmd != null && !string.IsNullOrEmpty(cmd.CommandText)) 
        { 
         cmd.Prepare(); 
         cmd.ExecuteNonQuery(); 
         cmd.Dispose(); 
         cmd = new SqlCommand("", conn, tran); 
         cmd.CommandType = System.Data.CommandType.Text; 
         batch_param_counter = 0; 
        } 
        tran.Commit(); 
        tran = null; 

        if (Console.KeyAvailable) 
         break; 

        cmd.Transaction = tran = conn.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted); 
       } 
       counter++; 
      } 

      if (cmd != null && !string.IsNullOrEmpty(cmd.CommandText)) 
      { 
       cmd.Prepare(); 
       cmd.ExecuteNonQuery(); 
       cmd.Dispose(); 
      } 
      if (tran != null) 
       tran.Commit(); 

      stopwatch.Stop(); 
     } 
+0

wsadka wsadowa co 200 sztuk –

Powiązane problemy