2011-06-17 12 views
9

Rozważmy następujący sqlWstaw do tabeli temp z procedury przechowywanej, która zwraca wiele zestawów wyników

Przechowywany proces o nazwie myProc, który zwraca dwa zestawy wyników. Zestaw wyników 1 zwraca kolumnę 1, kolumnę 2. Zestaw wyników 2 zwraca kolumnę 3, kolumnę 4, kolumnę 5.

Następujące sql nie powiedzie się, ponieważ tabela temp ma zdefiniowane tylko 2 kolumny wewnętrzne.

Create Table #temp1(
Column1 int, 
Column2 int) 

insert into #temp1 exec myProc 

Moje pytanie brzmi: czy można po prostu wstawić pierwszy zestaw wyników do # temp1?

+0

http://stackoverflow.com/questions/209383/select-columns-from-result-set-of-stored-procedure – THEn

+0

możliwy duplikat [JAK WYBRAĆ * NA \ [tabela tymczasowa \] FROM \ [Procedura przechowywana \]] (http://stackoverflow.com/questions/653714/how-to-select-into-temp-table-from -stored-procedure) –

Odpowiedz

2

Stary post, ale stanąłem w obliczu tego samego problemu i chociaż wspomniane powyżej odpowiedzi są nieco powiązane, pytanie OP dotyczy SP, który zwraca wiele zestawów. Jedynym rozwiązaniem, jakie mogłem znaleźć, oprócz przepisania SP, aby podzielić go na mniejsze SP, było napisanie procedury SQL CLR, która wykonuje SP i zwraca tylko wymagany zestaw wyników. Procedura uzyskuje indeks wymaganego zestawu wyników, wykonuje SqlCommand, aby uruchomić początkowe T-SQL SP, a następnie wykonuje pętle przez wyniki SqlDataReader, aż znajdzie żądany zestaw wyników i zwróci odpowiednie rekordy. Poniższy kod jest częścią procedury SQL CLR:

SqlDataReader rdr = command.ExecuteReader(); 
int index = 0; 
bool bContinue = true; 
while (index < resultSetIndex.Value) 
{ 
    if (!rdr.NextResult()) 
    { 
     bContinue = false; 
     break; 
    } 
    index++; 
} 
if (!bContinue) 
    throw new Exception("Unable to read result sets."); 

.......

List<SqlMetaData> metadataList = new List<SqlMetaData>(); 
for (int i = 0; i < rdr.FieldCount; i++) 
{ 
    string dbTypeName = rdr.GetDataTypeName(i); 
    SqlMetaData metadata; 
    if (dbTypeName.ToLower().Contains("char")) 
     metadata = new SqlMetaData(rdr.GetName(i), (SqlDbType)Enum.Parse(typeof(SqlDbType), dbTypeName, true), 50); 
    else 
     metadata = new SqlMetaData(rdr.GetName(i), (SqlDbType)Enum.Parse(typeof(SqlDbType), dbTypeName, true)); 
    metadataList.Add(metadata); 
} 
SqlDataRecord record = new SqlDataRecord(metadataList.ToArray()); 
object[] values = new object[rdr.FieldCount]; 
if (rdr.HasRows) 
{ 
    SqlContext.Pipe.SendResultsStart(record); 
    while (rdr.Read()) 
    { 
     rdr.GetValues(values); 
     record.SetValues(values); 
     SqlContext.Pipe.SendResultsRow(record); 
    } 
    SqlContext.Pipe.SendResultsEnd(); 
} 
+0

+1 poza uproszczeniem wyodrębniania metadanych z 'SqlDataReader' i tworzenia' SqlMetaData' dla 'SqlDataRecord', co może prowadzić do problemów w zależności od tego, jakie typy danych są zwracane, jest to dość to jedyny sposób, aby uzyskać określony zestaw wyników z procedury składowanej. –

1

Jest inny sposób

SELECT * into #temp 
    from OPENROWSET('SQLNCLI', 'Server=(local)\\(instance);Trusted_Connection=yes;', 
'EXEC (database).(schema).(sproc)') 

To będzie wstawić do pierwszego resultset # temp

Powiązane problemy