2013-08-29 13 views
9

Sto avendo per convertire un sistema ASP classico per C#restituire più set di record dal proc memorizzato in C#

Ho una stored procedure che può tornare fino a 7 recordsets (a seconda dei parametri passati a).

Ho bisogno di sapere come posso semplicemente restituire tutti i recordset come singoli DataTable in modo da poter scorrere tutto ciò che c'è, saltando al successivo DataTable quando arrivo alla fine senza dover eseguire più istruzioni SQL e utilizzare più adapter. Istruzioni di riempimento per aggiungere ciascuna tabella in un DataSet.

In classico era un semplice ciclo Do While not objRS.EOF con objRS.NextRecordset() quando sono arrivato alla fine del ciclo per passare all'istruzione successiva.

C'è qualcosa che posso usare che non richiede una riscrittura totale del codice di back-end corrente?

Ogni recordset ha un numero diverso di colonne e righe. Non sono collegati tra loro. Restituiamo più recordset da Stored Proc per ridurre il traffico.

Gli esempi sarebbero carini.

Grazie

risposta

11
SqlConnection con=new SqlConnection("YourConnection String"); 
SqlCommand cmd=new SqlCommand(); 
SqlDataAdapter da=new SqlDataAdapter(); 
DataSet ds = new DataSet(); 
cmd = new SqlCommand("name of your Stored Procedure", con); 
cmd.CommandType = CommandType.StoredProcedure; 
//cmd.Parameters.AddWithValue("@SuperID", id);//if you have parameters. 
da = new SqlDataAdapter(cmd); 
da.Fill(ds); 
con.Close(); 

Dopo questo si può prendere vantaggio di diversi (7) recordset utilizzando

ds.Tables[0] 
ds.Tables[1] 
ds.Tables[2] 
ds.Tables[3] 
ds.Tables[4] 
ds.Tables[5] 
ds.Tables[6] 
+0

Grazie, mi piace questa risposta puramente perché ho già una classe dati con funzioni wrapper che gestiscono le connessioni e smaltirle quando la classe viene distrutta ecc. Volevo solo usare una funzione esistente che Ho avuto e riferimento le tabelle all'interno del set di dati. – user2334626

5

questo restituirà tutto quello che dovete

using (SqlConnection conn = new System.Data.SqlClient.SqlConnection(connString)) 
{ 
    using (SqlCommand cmd = new SqlCommand()) 
    { 
     cmd.CommandText = "yoursp"; 
     cmd.Connection = conn; 
     cmd.CommandType = CommandType.StoredProcedure; 

     conn.Open(); 

     SqlDataAdapter adapter = new SqlDataAdapter(cmd); 

     DataSet ds = new DataSet(); 
     adapter.Fill(ds); 

     conn.Close(); 
    } 
} 
+2

Questo è quello che uso per ottenere più recordset da una stored procedure. Solo per chiarimenti, i recordset sono memorizzati in 'ds.Tables' e potresti voler inserire' DataSet ds = new DataSet(); 'all'inizio in modo che tu possa fare riferimento all'esterno dell'uso' (SqlConnection conn = new System.Data.SqlClient.SqlConnection (connString)) 'blocco. Solo un pensiero. – JoeFletch

+0

sì, è possibile spostarlo. dando solo un esempio di come farlo; – Ehsan

8

Se si riempie un DataSet utilizzando il metodo SqlDataAdapter.Fill() allora ciascuno dei tuoi recordset restituito dalla stored procedure verrà restituito come un DataTable all'interno della vostra dataset

DataSet dataset = new DataSet(); 
using (var adapter = new SqlDataAdapter("yourStoredProcedure", yourConnectionString)) 
{ 
    adapter.SelectCommand.CommandType = CommandType.StoredProcedure; 
    adapter.Fill(dataset); 
} 
for (int i = 0; i < dataset.Tables.Count; i++) 
{ 
    // Do something for each recordset 
} 

Se si utilizza uno SqlDataReader quindi uso può utilizzare il metodo di avanzare SqlDataReader.NextResult() al successivo set di record:

using (var connection = new SqlConnection(yourConnectionString)) 
using (var command = new SqlCommand("yourStoredProcedure")) 
{ 
    connection.Open(); 
    using (var reader = command.ExecuteReader()) 
    { 
     while (reader.Read()) 
     { 
      // do something with first result set; 
     } 
     if (reader.NextResult()) 
     { 
      while (reader.Read()) 
      { 
       // do something with second result set; 
      } 
     } 
     else 
     { 
      return; 
     } 
     if (reader.NextResult()) 
     { 
      while (reader.Read()) 
      { 
       // do something with third result set; 
      } 
     } 
     else 
     { 
      return; 
     } 
    } 
} 
+0

Non ho mai saputo che si potesse ottenere più set di risultati con 'SqlDataReader' con' .ExecuteReader() 'e' .NextResult() '. Grazie per la risposta dettagliata! – JoeFletch

+2

In effetti è possibile, generalmente preferisco lavorare con SqlDataReader a causa dell'utilizzo della memoria inferiore memorizzando solo il record corrente e non preoccupandomi di ciò che è già stato letto e di ciò che è ancora da leggere. Tuttavia esiste una grande analogia in [questa risposta] (http://stackoverflow.com/a/1083223/1048425) che confronta i set di dati con i datareader. – GarethD

+0

Grazie per aver condiviso il link SO! Ho usato 'SqlDataReader's in passato e ho pensato che fosse un sacco di codice da mantenere. Ho quindi provato 'DataTables' e ho pensato che fossero molto più veloci. Dovrò tenere a mente le alternative quando scrivo del codice aggiuntivo in futuro! Ancora una volta, grazie per la condivisione! – JoeFletch

0

si può verificare se il dott ha più di record No ot utilizzando if (dr.NextResult())

e poi di nuovo con ciclo dr.read

provare questo

string connStr = ConfigurationManager.ConnectionStrings["ConString"].ConnectionString; 
SqlConnection Con = new SqlConnection(connStr); 

try 
{ 
    string str1 = "select productid,productname from products;select VendorFName from vendor"; 
    SqlCommand com = new SqlCommand(str1, Con); 

    com.Connection.Open(); 

    SqlDataReader dr = com.ExecuteReader(); 

    DropDownList1.Items.Add("Select Product Id"); 
    DropDownList2.Items.Add("Select Vendor Name"); 

    while(dr.Read()) 
    { 
     DropDownList1.Items.Add(dr.GetValue(0).ToString()); 
    } 

    if (dr.NextResult()) 
    { 
     while (dr.Read()) 
     { 
      DropDownList2.Items.Add(dr.GetValue(0).ToString()); 
     } 
    } 
} 
catch (Exception ex) 
{ 
} 
finally 
{ 
    if (Con.State == ConnectionState.Open) 
    { 
     Con.Close(); 
    } 
} 
Problemi correlati