Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Insérer dans une table temporaire à partir d'une procédure stockée qui renvoie plusieurs jeux de résultats

Ancien message, mais j'ai rencontré le même problème et bien que les réponses mentionnées ci-dessus soient un peu liées, la question de l'OP concerne le SP qui renvoie plusieurs ensembles. La seule solution que j'ai pu trouver, à part réécrire le SP pour le diviser en SP plus petits, était d'écrire un SQL CLR procédure qui exécute le SP et renvoie uniquement le jeu de résultats requis. La procédure obtient l'index du jeu de résultats requis, exécute un SqlCommand pour exécuter le T-SQL initial SP, puis boucle à travers un SqlDataReader résultats jusqu'à ce qu'il trouve le jeu de résultats souhaité et renvoie les enregistrements correspondants. Le code suivant fait partie du SQL CLR procédure :

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();
}