2011-06-17 20 views
9

Consideremos el siguiente código SQLInsertar en la tabla temporal de un procedimiento almacenado que devuelve varios conjuntos de resultados

un procedimiento almacenado llamado myProc que devuelve dos conjuntos de resultados. El conjunto de resultados 1 devuelve column1, column2. El conjunto de resultados 2 devuelve la columna 3, la columna 4, la columna 5.

El sql siguiente fallará ya que la tabla temporal solo ha definido 2 columnas int.

Create Table #temp1(
Column1 int, 
Column2 int) 

insert into #temp1 exec myProc 

Mi pregunta es ¿es posible simplemente insertar el primer conjunto de resultados en # temp1?

+0

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

+0

posible duplicado de [Cómo SELECCIONAR * INTO \ [tabla temporal \] FROM \ [Procedimiento almacenado]] (http://stackoverflow.com/questions/653714/how-to-select-into-temp-table-from -stored-procedure) –

Respuesta

2

Publicación anterior, pero me enfrenté al mismo problema y aunque las respuestas mencionadas anteriormente están un poco relacionadas, la pregunta del OP es sobre SP que devuelve varios conjuntos. La única solución que pude encontrar, además de reescribir el SP para dividirlo en SP más pequeños, fue escribir un procedimiento SQL CLR que ejecuta el SP y devuelve solo el conjunto de resultados requerido. El procedimiento obtiene el índice del conjunto de resultados requerido, ejecuta un SqlCommand para ejecutar el SP inicial T-SQL, luego recorre un resultado de SqlDataReader hasta que encuentra el conjunto de resultados deseado y devuelve los registros correspondientes. El código siguiente es parte del procedimiento 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 fuera de la simplificación excesiva de extraer los metadatos del 'SqlDataReader' y la creación de' SqlMetaData' para 'SqlDataRecord' que puede generar problemas dependiendo de qué tipo de datos se devuelvan, esto es bastante la única forma de obtener un conjunto de resultados específico a partir de un Procedimiento almacenado. –

1

Hay otra manera

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

Esto va a insertar el primer conjunto de resultados en # temp

Cuestiones relacionadas