<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://geeks.ms/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>SqlRanger</title><link>http://geeks.ms/blogs/sqlranger/default.aspx</link><description>El blog de Jesús López</description><dc:language /><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Llamar a servicios web desde dentro de SQL Server 2005</title><link>http://geeks.ms/blogs/sqlranger/archive/2006/04/06/105.aspx</link><pubDate>Thu, 06 Apr 2006 11:36:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:105</guid><dc:creator>SqlRanger</dc:creator><slash:comments>29</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/sqlranger/rsscomments.aspx?PostID=105</wfw:commentRss><comments>http://geeks.ms/blogs/sqlranger/archive/2006/04/06/105.aspx#comments</comments><description>&lt;P&gt;El otro día, por diversión, me dio por jugar a llamar a un servicio web desde un procedimiento almacenado de SQL Server 2005 escrito en C#. La cosa parecía fácil y divertida, pero de eso nada, no había manera de hacer funcionar aquello.... Por fin, después de buscar un rato por el Google encontré la solución a mis problemas. Para evitar que a vosotros también os pase lo mismo, quisiera compartir con todos vosotros esta experiencia que os permitirá saber de antemano los problemas que os vais a encontrar al hacer este tipo de cosas y como solucionarlos. &lt;/P&gt;
&lt;P&gt;Para empezar supongamos que tenemos una solución en Visual Studio 2005 con un sitio web donde está definido el siguiente servicio web accesible mediante la url &lt;A href="http://localhost/ServiciosWeb/ServicioWeb.asmx"&gt;http://localhost/ServiciosWeb/ServicioWeb.asmx&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;public class ServicioWeb : System.Web.Services.WebService &lt;BR&gt;{&amp;nbsp;&lt;BR&gt;&amp;nbsp; [WebMethod]&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;public string RealizarProceso(int IdProceso)&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (IdProceso % 5 == 0)&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new SoapException("No me gustan los múltiplos de cinco",&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SoapException.ClientFaultCode);&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return "Proceso número " + IdProceso.ToString() + &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; " realizado correctamente";&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;} &lt;BR&gt;} &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Supongamos también que creamos un proyecto de SQL Server de nombre ServiciosWebClr. Lo primero que se nos ocurre es añadir una referencia web al servicio, a la que llamamos ServiciosWeb. Luego añadirmos un procedimiento almacenado llamado RealizarProceso con este código:&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;using System.Data.SqlTypes;&lt;BR&gt;using Microsoft.SqlServer.Server;&lt;BR&gt;using ServiciosWebClr.ServiciosWeb;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&lt;BR&gt;public partial class StoredProcedures&lt;BR&gt;{&lt;BR&gt;&amp;nbsp; [Microsoft.SqlServer.Server.SqlProcedure]&lt;BR&gt;&amp;nbsp;&amp;nbsp;public static void RealizarProceso(SqlInt32 IdProceso)&lt;BR&gt;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; using (ServicioWeb sw = new ServicioWeb())&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string Resultado = sw.RealizarProceso(IdProceso.Value);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;};&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Para que un procedimiento almacenado CLR pueda llamar a un servicio web, el ensamblado en el que reside tiene que tener permiso de EXTERNAL ACCESS. Para ello vamos a las propiedades del proyecto, ficha database y seleccionamos external en el cuadro combinado permission level. Pero esto no es suficiente. Si intentamos desplegar (deploy) el proyecto recibiremos el siguiente error:&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;FONT face="Courier New" color=#ff0000 size=2&gt;CREATE ASSEMBLY for assembly 'ServiciosWebClr' failed because assembly 'ServiciosWebClr' is not authorized for PERMISSION_SET = EXTERNAL_ACCESS.&amp;nbsp; The assembly is authorized when either of the following is true: the database owner (DBO) has EXTERNAL ACCESS ASSEMBLY permission and the database has the TRUSTWORTHY database property on; or the assembly is signed with a certificate or an asymmetric key that has a corresponding login with EXTERNAL ACCESS ASSEMBLY permission.&amp;nbsp;ServiciosWebClr&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Para solucionarlo ejecutamos la siguiente sentencia en el Management Studio:&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;ALTER DATABASE &amp;lt;base de datos&amp;gt; SET TRUSTWORTHY ON&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Con esto ya podremos desplegar el proyecto en SQL Server. Pero&amp;nbsp;si ejecutamos este procedimiento almacenado en el Management Studio, nos encontramos con otro problema, recibimos el siguiente mensaje de error:&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;FONT face="Courier New" color=#ff0000 size=2&gt;Msg 6522, Level 16, State 1, Procedure RealizarProceso, Line 0&lt;BR&gt;A .NET Framework error occurred during execution of user defined routine or aggregate 'RealizarProceso': &lt;BR&gt;System.InvalidOperationException: Cannot load dynamically generated serialization assembly. In some hosting environments assembly load functionality is restricted, consider using pre-generated serializer. Please see inner exception for more information. ---&amp;gt; System.IO.FileLoadException: LoadFrom(), LoadFile(), Load(byte[]) and LoadModule() have been disabled by the host.&lt;BR&gt;etc etc.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Los servicios web&amp;nbsp;serializan y deserializan los objetos en formato&amp;nbsp;XML.&amp;nbsp;Para realizar estas operaciones&amp;nbsp;utilizan un XmlSerializer el cual&amp;nbsp;genera y carga en tiempo de ejecución un ensamblado con clases especializadas en serializar y deserializar los tipos de nuestro&amp;nbsp; ensamblado. Por razones de seguridad y fiabilidad, SQL Server no permite cargar ensamblados en tiempo de ejecución, por eso recibimos esta excepción.&lt;/P&gt;
&lt;P&gt;La solución, como sugiere el mesaje de error, es utitlizar un serializador XML pregenerado. Entre las herramientas de línea de comandos, tenemos SGen.exe que genera un ensamblado para serialización XML. Pero es más sencillo ir a las propiedades del proyecto, ficha build y seleccionar on en el cuadro combinado generate serialization assembly. Con esto, se generará el ensamblado ServiciosWebClr.XmlSerializers.dll cada vez que generemos el proyecto. Pero este ensamblado no se instala automáticamente en SQL Server, tenemos que hacerlo nosotros manualmente. Para ello añadimos los scripts predeployscript.sql y postdeployscript.sql en la raíz del proyecto (no en la carpeta Test Scripts) con el siguiente contenido:&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Predeployscript.sql:&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;IF EXISTS (SELECT [name] &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; FROM sys.assemblies &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WHERE [name] = N'ServiciosWebClr.XmlSerializers')&lt;BR&gt;DROP ASSEMBLY [ServiciosWebClr.XmlSerializers] &lt;BR&gt;WITH NO DEPENDENTS&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face="Courier New" size=2&gt;
&lt;P&gt;&lt;BR&gt;&lt;FONT face="Times New Roman" size=3&gt;Postdeployscript.sql:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;CREATE ASSEMBLY [ServiciosWebClr.XmlSerializers]&lt;BR&gt;FROM '&amp;lt;path&amp;gt;\ServiciosWebClr.XmlSerializers.dll'&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Con esto ya debería funcionar.&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Otra cuestión es que la mayoría de las veces&amp;nbsp;no resulta adecuado&amp;nbsp;llamar al servicio web de forma síncrona, ya que normalmente la llamada tarda algunos segundos. Así que veamos qué pasa cuando llamamos a los servicios web de forma asíncrona. &lt;/P&gt;
&lt;P&gt;Supongamos que&amp;nbsp;creamos la siguiente tabla y procedimiento almacenado para registrar todas las llamadas al servicio web, incluyendo el resultado, información de tiempos y errores:&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;CREATE TABLE RegistroProcesos&lt;BR&gt;(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IdRegistro int IDENTITY(1,1) PRIMARY KEY,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IdProceso int NOT NULL,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Comienzo datetime NOT NULL,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Fin datetime NOT NULL,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Correcto bit NOT NULL DEFAULT 1,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Resultado varchar(100),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DescripcionError varchar(1000)&lt;BR&gt;)&lt;/FONT&gt;&lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;GO&lt;BR&gt;&amp;nbsp;&lt;BR&gt;CREATE PROCEDURE RegistrarProceso&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @IdProceso int,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Comienzo datetime,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Fin datetime,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Correcto bit,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Resultado varchar(100),&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @DescripcionError varchar(1000)&lt;BR&gt;AS&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; INSERT INTO RegistroProcesos(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IdProceso, Comienzo, Fin,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Correcto, Resultado, DescripcionError)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; VALUES (&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @IdProceso, @Comienzo, @Fin,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; @Correcto, @Resultado, @DescripcionError)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Nuestra clase StoredProcedures podría ser la siguiente:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;public partial class StoredProcedures&lt;BR&gt;{&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp; private class Estado&lt;BR&gt;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public int IdProceso;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public ServicioWeb ServicioWeb;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public DateTime Comienzo;&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public Estado(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;int IdProceso, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ServicioWeb ServicioWeb, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DateTime Comienzo)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.IdProceso = IdProceso;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.ServicioWeb = ServicioWeb;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;this.Comienzo = Comienzo;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;[Microsoft.SqlServer.Server.SqlProcedure]&lt;BR&gt;&amp;nbsp;&amp;nbsp;public static void RealizarProceso(SqlInt32 IdProceso)&lt;BR&gt;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ServicioWeb sw = new ServicioWeb();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Estado Estado = new Estado(IdProceso.Value, sw, DateTime.Now);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sw.BeginRealizarProceso(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IdProceso.Value, DelegadoProcesoRealizado, Estado);&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp; private static readonly AsyncCallback DelegadoProcesoRealizado =&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new AsyncCallback(ProcesoRealizado);&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp; private static void ProcesoRealizado(IAsyncResult ar)&lt;BR&gt;&amp;nbsp; {&lt;BR&gt;&amp;nbsp; &amp;nbsp; Estado Estado = (Estado)ar.AsyncState;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; String Resultado = Estado.ServicioWeb.EndRealizarProceso(ar);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;RegistrarProceso(Estado.IdProceso, Estado.Comienzo,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DateTime.Now, true, Resultado, null);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;catch (Exception ex)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; RegistrarProceso(Estado.IdProceso, Estado.Comienzo,&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DateTime.Now, false, null, ex.Message);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private const string ConnectionString = &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Data Source=(local);Integrated Security=SSPI;" +&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;"Initial Catalog=AdventureWorks";&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;private static void RegistrarProceso(&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int IdProceso,&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DateTime Comienzo, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DateTime Fin, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bool Correcto, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string Resultado, &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string DescripcionError)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using (SqlConnection cn = new SqlConnection(ConnectionString))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using (SqlCommand cmd = new SqlCommand("RegistrarProceso", cn))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; cmd.CommandType = CommandType.StoredProcedure;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmd.Parameters.Add("@IdProceso", SqlDbType.Int).Value =&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IdProceso;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmd.Parameters.Add("@Comienzo", SqlDbType.DateTime).Value =&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Comienzo;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmd.Parameters.Add("@Fin", SqlDbType.DateTime).Value = Fin;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmd.Parameters.Add("@Correcto", SqlDbType.Bit).Value =&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Correcto;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmd.Parameters.Add("@Resultado",SqlDbType.VarChar, 100).Value =&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Resultado == null ? (object) DBNull.Value : &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (object) Resultado;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmd.Parameters.Add("@DescripcionError", &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SqlDbType.VarChar, 1000).Value =&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; DescripcionError == null ? (object) DBNull.Value : &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (object) DescripcionError;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cn.Open();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmd.ExecuteNonQuery();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Observa que la cadena de conexión no es "context connection=true", sino una cadena de conexión regular. Esto es así porque el método de devolución de llamada ProcesoRealizado se ejecuta en un hilo diferente que el procedimiento almacenado, este hilo no es un hilo de ejecución de SQL Server así que no se puede usar la conexión de contexto. &lt;/P&gt;
&lt;P&gt;Si desplegamos ahora el proyecto y ejecutamos lo siguiente en el ManagementStudio:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;TRUNCATE TABLE RegistroProcesos&lt;BR&gt;DECLARE @IdProceso int&lt;BR&gt;SET @IdProceso = 1&lt;BR&gt;WHILE @IdProceso &amp;lt;= 10&lt;BR&gt;BEGIN&lt;BR&gt;&amp;nbsp; EXEC RealizarProceso @IdProceso&lt;BR&gt;&amp;nbsp; SET @IdProceso = @IdProceso + 1&lt;BR&gt;END &lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Y luego ejecutamos;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;SELECT * FROM RegistroProcesos&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Veremos que el procedimiento almacenado funciona como se espera.&lt;/P&gt;
&lt;P&gt;Pues nada más, espero que esto os sirva de ayuda y os quite algún que otro quebradero de cabeza si es que alguna vez necesitáis llamar a un servicio web desde dentro de SQL Server 2005.&lt;/P&gt;
&lt;P&gt;Un&amp;nbsp;saludo:&lt;/P&gt;
&lt;P&gt;Jesús López&lt;BR&gt;&amp;nbsp;&lt;/P&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=105" width="1" height="1"&gt;</description></item></channel></rss>
