2

Environnement: C#, .Net 3.5, Sql Server 2005Pourquoi la procédure CLR SQL Server se bloquer dans GetResponse() appel au service Web

J'ai une méthode qui fonctionne dans un autonome C# projet d'application de la console. Il crée un XMLElement à partir des données de la base de données et utilise une méthode privée pour l'envoyer à un service Web sur notre réseau local. Lorsqu'il est exécuté à partir de VS dans ce projet de test, il s'exécute en < 5 secondes.

J'ai copié la classe dans un projet CLR, l'ai compilé et l'ai installé dans SQL Server (WITH PERMISSION_SET = EXTERNAL_ACCESS). La seule différence est les appels SqlContext.Pipe.Send() que j'ai ajouté pour le débogage.

Je le teste en utilisant une procédure stockée de commande EXECUTE (dans le CLR) à partir d'une fenêtre de requête SSMS. Il ne revient jamais. Lorsque j'arrête l'exécution de l'appel après une minute, la dernière chose affichée est "Appel GetResponse() en utilisant http://servername:53694/odata.svc/Customers/". Des idées sur pourquoi l'appel GetResponse() ne retourne pas lors de l'exécution dans SQL Server?

private static string SendPost(XElement entry, SqlString url, SqlString entityName) 
{ 
    // Send the HTTP request 
    string serviceURL = url.ToString() + entityName.ToString() + "/"; 
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(serviceURL); 
    request.Method = "POST"; 
    request.Accept = "application/atom+xml,application/xml"; 
    request.ContentType = "application/atom+xml"; 
    request.Timeout = 20000; 
    request.Proxy = null; 

    using (var writer = XmlWriter.Create(request.GetRequestStream())) 
    { 
     entry.WriteTo(writer); 
    } 

    try 
    { 
     SqlContext.Pipe.Send("Calling GetResponse() using " + request.RequestUri); 
     WebResponse response = request.GetResponse(); 
     SqlContext.Pipe.Send("Back from GetResponse()"); 

     /* 
     string feedData = string.Empty; 

     Stream stream = response.GetResponseStream(); 
     using (StreamReader streamReader = new StreamReader(stream)) 
     { 
      feedData = streamReader.ReadToEnd(); 
     } 
     */ 

     HttpStatusCode StatusCode = ((HttpWebResponse)response).StatusCode; 
     response.Close(); 

     if (StatusCode == HttpStatusCode.Created /* 201 */) 
     { 
      return "Created @ Location= " + response.Headers["Location"]; 
     } 

     return "Creation failed; StatusCode=" + StatusCode.ToString(); 
    } 
    catch (WebException ex) 
    { 
     return ex.Message.ToString(); 
    } 
    finally 
    { 
     if (request != null) 
      request.Abort(); 

    } 
} 

Répondre

2

Le problème s'est avéré être la création du contenu de la requête à partir du XML. L'original:

using (var writer = XmlWriter.Create(request.GetRequestStream())) 
{ 
    entry.WriteTo(writer); 
} 

Le remplacement de travail:

using (Stream requestStream = request.GetRequestStream()) 
    { 
     using (var writer = XmlWriter.Create(requestStream)) 
     { 
      entry.WriteTo(writer); 
     } 
    } 
-1

Vous demandez des difficultés à faire cela dans le CLR. Et vous dites que vous appelez cela d'un déclencheur? Cela appartient au niveau de l'application.

Ce genre de choses est la raison pour laquelle, lorsque la fonctionnalité CLR est apparue, les administrateurs de base de données étaient très préoccupés par la façon dont il serait mal utilisé.

+0

Je ne connais aucun moyen pour que quelque chose dans la couche d'application soit appelée lorsqu'un déclencheur de base de données est déclenché. –

0

Vous devez disposer WebResponse. Sinon, après quelques appels, le délai d'attente est dépassé.

Questions connexes