mayo 06, 2008

Usar una DLL desde SQL Server 2005

Este es mi primer tutorial en un blog, espero que sea de utilidad para los lectores.
Este tutorial pretende mostrar cómo utilizar una DLL desde SQL Server 2005 describiendo el código de la DLL en C# y las instrucciones para utilizar la DLL desde la consola de SQL Server 2005.

El ejemplo que se toma es hacer el envío de un mail desde una función o procedimiento almacenado. La DLL escrita en C# tiene 2 métodos: EnviarCorreo y EscribirLog. Se crea una función que esté asociada a un assembly representado por la DLL y al hacer uso de la función se invoca el método EnviarCorreo lo cual permite enviar un correo desde la base de datos através de la función.

Este es el código de la DLL en C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Mail;
using System.Text;

namespace Comunicacion
{
public class Mensaje
{
public static bool EnviarCorreo(string to, string from, string subject, string body)
{
// Se crea el mensaje
MailMessage mensaje = new MailMessage(from, to);
mensaje.Subject = subject;
mensaje.Body = body;

// Se establece una referencia la servidor SMTP
SmtpClient cliente = new SmtpClient("smtp.gmail.com", 25);
cliente.UseDefaultCredentials = true;

try
{
// Se envia el mail
cliente.Send(mensaje);
return true;
}
catch (Exception ex)
{
return false;
}
}

public static bool EscribirLog(string to, string from, string subject, string body)
{
// Mensaje que será escrito en el archivo
string mensaje = String.Format("Se envió un mensaje a: {0} - desde: {1} con asunto: {2}. Mensaje: {3}", to, from, subject, body);

try
{
// Se crea una referencia al archivo
StreamWriter outFile = System.IO.File.AppendText("c:\\logBD.txt");

// Se escribe el mensaje
outFile.WriteLine(mensaje);

// Se cierra el archivo
outFile.Close();
return true;
}
catch(Exception ex)
{
return false;
}

}
}
}

Se habilita SQL Server 2005 para usar DLL's

exec sp_configure 'clr enabled',1
reconfigure
go

Se habilita la base de datos para que acepte peticiones del CLR.
Para el ejemplo la base de datos se llama PruebaDLL

ALTER DATABASE PruebaDLL SET TRUSTWORTHY ON

Se crea el assembly en la base de datos a partir de la DLL.
Hay varios tipos de permisos pero para que inicialmente no haya problemas se usa UNSAFE.

CREATE ASSEMBLY Comunicaciones FROM 'C:\Comunicacion.dll' WITH PERMISSION_SET = UNSAFE

Se crea una función que consumirá el assembly. Para el ejemplo, la función se llama enviarCorreo. Al final de la función se especifica el assembly al cual estará asociada la función.
La estructura de EXTERNAL NAME es:
NombreDelAssembly.[NombreClase].MetodoDeLaClase
El nombre de la clase debe incluir su namespace. (fully qualified name)

CREATE FUNCTION dbo.enviarCorreo
(
@to as nvarchar(MAX),
@from as nvarchar(MAX),
@subject as nvarchar(MAX),
@body as nvarchar(MAX)
)
RETURNS bit
AS EXTERNAL NAME Comunicaciones.[Comunicacion.Mensaje].EnviarCorreo

Este es el uso de la función desde la consola de SQL Server 2005:

dbo.enviarCorreo 'johncardozo@gmail.com',
'batman@ligajusticia.com',
'Prueba desde SQL server',
'Este es un mail enviado desde SQL server 2005 atraves de una DLL hecha en .Net'

PD. Se reciben comentarios acerca del contenido y del estilo del tutorial para mejorar posibles posteriores artículos, tutoriales, etc.

8 comentarios:

GabrieL dijo...

no le tengo q pasar mi usuario y password para que pueda usar el smtp de gmail???

John Cardozo dijo...

No, con la instrucción:
cliente.UseDefaultCredentials = true;
es suficiente.
Todo depende del servidor SMTP que se estè utilizando para el envío.

GabrieL dijo...

lo estoy probando con mi cta de Gmail y no se si tengo q usar algo mas...

John Cardozo dijo...

Si es con GMail no hay que hacer nada mas...

Anónimo dijo...

Msg 6544, Level 16, State 1, Line 1
CREATE ASSEMBLY for assembly 'CardNumberCrypto' failed because assembly 'funcionencryta' is malformed or not a pure .NET assembly.
Unverifiable PE Header/native stub.



me sale este error alguna idea de por q

John Cardozo dijo...

Mis pruebas se hicieron utilizando .Net para crear la DLL. No se si se comporte de la misma manera utilizando otro tipo de tecnologia para la DLL. Podrías ser más específic@ acerca de la forma en que se está generando la DLL?

Anónimo dijo...

El método, la propiedad o el campo 'genera_entero' de la clase 'CalculoPremio.CalculoPremio.Calculo' del ensamblado 'CalculoPremio' no es estático. ME SALE ESE ERROR

Anónimo dijo...

Excelente explicación.