Enviar correo desde Sql Server utilizando cuenta de gmail / Send email from Sql Server using gmail account


Acá va el detalle de como enviar correo electrónico desde SQL Server, utilizando Stored Procedures y utilizando como servidor de salida una cuenta de gmail.

1) En el servidor Sql, debemos habilitar la opción “Ole Automation Procedures” que por defecto está deshabilitada, para que nos permita llamar aplicaciones externas al servidor. Desde la consola ejecutamos la siguiente consulta:

EXEC sp_configure 'show advanced option', 1
RECONFIGURE
EXEC sp_configure 'Ole Automation Procedures', 1;
RECONFIGURE

2) Instalamos la aplicación gratuita easendmail de emailarchitect.net que permite realizar el dialogo del servidor smtp con gmail, entre otros proveedores de correo.

3) Creamos un sp que nos permitirá llamar a esta aplicacion y enviar correo. Gracias emailarchitect.net

CREATE PROCEDURE [dbo].[usp_SendTextEmail]  @ServerAddr nvarchar(128),
@From nvarchar(128),
@To nvarchar(1024),
@Subject nvarchar(256),
@Bodytext nvarchar(max) = 'This is a test text email from MS SQL server, do not reply.',
@User nvarchar(128) = '',
@Password nvarchar(128) = '',
@SSLConnection int = 0,
@ServerPort int = 25

AS

DECLARE @hr int
DECLARE @oSmtp int
DECLARE @result int
DECLARE @description nvarchar(255)

EXEC @hr = sp_OACreate 'EASendMailObj.Mail',@oSmtp OUT 
If @hr <> 0 
BEGIN
    PRINT 'Please make sure you have EASendMail Component installed!'
    EXEC @hr = sp_OAGetErrorInfo @oSmtp, NULL, @description OUT
    IF @hr = 0
    BEGIN
        PRINT @description
    END
    RETURN
End

EXEC @hr = sp_OASetProperty @oSmtp, 'LicenseCode', 'TryIt'
EXEC @hr = sp_OASetProperty @oSmtp, 'ServerAddr', @ServerAddr
EXEC @hr = sp_OASetProperty @oSmtp, 'ServerPort', @ServerPort

EXEC @hr = sp_OASetProperty @oSmtp, 'UserName', @User
EXEC @hr = sp_OASetProperty @oSmtp, 'Password', @Password

EXEC @hr = sp_OASetProperty @oSmtp, 'FromAddr', @From

EXEC @hr = sp_OAMethod @oSmtp, 'AddRecipientEx', NULL,  @To, 0

EXEC @hr = sp_OASetProperty @oSmtp, 'Subject', @Subject 
EXEC @hr = sp_OASetProperty @oSmtp, 'BodyText', @BodyText 

If @SSLConnection > 0 
BEGIN
    EXEC @hr = sp_OAMethod @oSmtp, 'SSL_init', NULL
END

PRINT 'Start to send email ...' 

EXEC @hr = sp_OAMethod @oSmtp, 'SendMail', @result OUT 

If @hr <> 0 
BEGIN
    EXEC @hr = sp_OAGetErrorInfo @oSmtp, NULL, @description OUT
    IF @hr = 0
    BEGIN
        PRINT @description
    END
    RETURN
End

If @result <> 0 
BEGIN
    EXEC @hr = sp_OAMethod @oSmtp, 'GetLastErrDescription', @description OUT
    PRINT 'failed to send email with the following error:'
    PRINT @description
END
ELSE 
BEGIN
    PRINT 'Email was sent successfully!'
END

EXEC @hr = sp_OADestroy @oSmtp

Go

4) Ya estamos en condiciones de enviar email desde Sql Server. En una ventana nueva de la consola podemos ejecutar:

/* Gmail SMTP server address */
DECLARE @ServerAddr nvarchar(128)
Set @ServerAddr = 'smtp.gmail.com'

/* Set your Gmail email address */
DECLARE @From nvarchar(128)
Set @From = 'direccionorigen@gmail.com'

DECLARE @To nvarchar(1024)
/*You can input multiple recipients and use comma (,) to separate multiple addresses */
Set @To = 'direcciondestino@gmail.com'

DECLARE @Subject nvarchar(256)
Set @Subject = 'prueba envio de correo desde sql server'

DECLARE @Bodytext nvarchar(512)
Set @BodyText = 'Este es un mesaje de prueba. No responda.'

/* Gmail user authentication should use your Gmail email address as the user name. */
DECLARE @User nvarchar(128)
Set @User = 'direccionorigen@gmail.com'

DECLARE @Password nvarchar(128)
Set @Password = 'su password'

/* Enable SSL/TLS */
DECLARE @SSL int
Set @SSL = 1

/* If you want to use TLS, please set it to 25 or 587 */
DECLARE @Port int
Set @Port = 465

PRINT 'start to send email ...'

exec usp_SendTextEmail @ServerAddr, @From, @To, @Subject, @BodyText, @User, @Password, @SSL, @Port

Ejecutamos y listo.

 

Acceder a servidor SQL Server en Servidor Virtual Azure / Connect to SQL Server on Azure Server


Si necesitamos acceder desde un equipo cualquiera a un servidor de base de datos SQL Server hosteado en una máquina virtual Azure, debemos hacer dos cosas en el servidor virtual:

1) Mapear el puerto 1433 para tener acceso al motor de la base de datos.

Esto lo hacemos en el gestor de máquinas virtuales, seleccionando nuestra máquina virtual, luego EndPoints y agregando una nueva regla.

windowsAzure_endpoints

2) Permitir conexiones entrantes al puerto 1433 en el firewall de Windows.

Esto asumo que ya saben como hacerlo, pero basicamente es agregar una regla en Panel de Control –> Firewall, permitiendo la entrada de los paquetes entrantes por TCP al puerto 1433.

Conectar a Servidor SQL Server por puerto no standard / sql server connect to a different port


Este dato es importante (al menos para mí) porque es distinto del criterio utilizado en la mayoría de las aplicaciones.

Si necesitamos conectar a un servidor MS Sql Server a través de un puerto distinto del standard (1433), debemos hacerlo de la siguiente manera:

NOMBRE_SERVIDOR\SQLEXPRESS,14333

Es decir, nombre de servidor, nombre de instancia, coma, numero de puerto.

La intuición me decía hacer NOMBRE_SERVIDOR:1433\SQLEXPRESS. Pero NO.

Esto es aplicable para conexiones desde el SQL Management Studio y también para las cadenas de conexión o connection strings.

Instalar Servidor SVN en Maquina Virtual Windows Azure / Visual SVN on Windows Azure Virtual Machine


Hace unos días descubrí un servicio de Microsoft para Emprendedores, (gracias Daniel Levi), llamado BizSpark,  que puede resultarnos muy útil en entornos de desarrollo, dado que nos proporciona software para desarrollo sin costo, hosting, entre otros beneficios.

Adicionalmente, obtenemos una cuenta de Windows Azure, donde podemos configurar una máquina virtual con buenos recursos a nuestra disposición y sin costo.

Sin embargo, no pasará mucho tiempo, antes de preguntarnos como hacemos para instalar un servidor svn en dicha cuenta, así que acá dejo una guía de configuración de un servidor svn en un servidor virtual Windows Azure (Gracias Marco Pasin – Microsoft SW Artchitect):

windowsazure_visualsvnquickstart

Enjoy !

Utilizar Lista de Parámetros en Stored Procedure


Tal vez se encuentren en la situación, donde deban pasarle una lista variable de parámetros a un sp. Por ejemplo, supongamos que se seleccionan los id de cliente 1,27,345,73 y deben pasarse a un sp que debe consultar los datos de los id de cliente seleccionados.

Tenemos varias soluciones posibles, inclusive, en SQL Server 2008 es posible solucionarlo utilizando un xml pasado por parámetro, pero vamos a aproximar una solución mas general, que nos sirva para diferentes motores.

Lo que hacemos es crear una función, a la que le pasamos la lista de ids separada por comas, y nos devolverá los id en una tabla que utilizaremos para filtrar los ids en la consulta de clientes.

La función:

CREATE FUNCTION intlist_to_tbl
(@list nvarchar(MAX))
RETURNS @tbl TABLE (number int NOT NULL) 
AS
BEGIN
   DECLARE @pos        int,
           @nextpos    int,
           @valuelen   int

   SELECT @pos = 0, @nextpos = 1

   WHILE @nextpos > 0
   BEGIN
      SELECT @nextpos = charindex(',', @list, @pos + 1)
      SELECT @valuelen = CASE WHEN @nextpos > 0
                              THEN @nextpos
                              ELSE len(@list) + 1
                         END - @pos - 1
      INSERT @tbl (number)
         VALUES (convert(int, substring(@list, @pos + 1, @valuelen)))
      SELECT @pos = @nextpos
   END
   RETURN
END

El procedimiento:

CREATE PROCEDURE consultarListaClientes 
@ids varchar(50) 
AS
   SELECT id, razonsocial
   FROM   clientes 
   inner join intlist_to_tbl(@ids) i ON clientes.id = i.number

La llamada:

EXEC consultarListaClientes '1, 27, 345, 73'

Vale aclarar que esta solución no es la mas rápida, en terminos de velocidad, si la cantidad de ids a consultar es muy grande, será lenta, pero nos servirá para resolver muchas situaciones simples.

Utilizando parámetros opcionales en Sql Server Stored Procedure


Supongamos que tenemos un programa que realiza una consulta a una base de datos sql server a través de un stored procedure. Ese programa debe pasarle parámetros, o no, en función de las selecciones del usuario.

En otro post, vimos como podemos pasarle parametros null a un stored procedure. Ahora vamos a utilizarlo para armar una consulta de acuerdo a criterios variables:

CREATE procedure [dbo].[ConsultaPorCriterios]
@idProvincia int,
@superficieMin float,
@superficieMax float,
@dni as varchar(10)
AS

select   idProvincia
        , superficie
        , dni
from tablita
where    (idPersona = @idPersona or @idPersona is null) and
         ((superficie between @superficieMin and @superficieMax) or @superficieMax is null) and
         (dni = @dni or @dni is null)

Pasando parametros null a Sql Server


Aquí un pequeño ejemplo de como pasar parámetros null con C# a un stored procedure en sql server:

        public DataTable Consulta(int? id)
        {
            string[] NomParam = new string[] { "id"};
            object[] arg = new object[] { id == null ? System.Data.SqlTypes.SqlInt32.Null : Int32.Parse(id.ToString()) };

            return conn.execSP("spConsula", arg, NomParam);
        }

El parámetro debe declararse con el simbolo “?” que le indica al compilador que puede venir un null en vez de un int. Luego, el tipo de datos es convertido a su equivalente nulo para sql server, de manera que interprete que es un parámetro con valor null y no que falta un parámetro.

 

Configuración Regional y de Idioma en SQL Server


Después de luchar un par de horas con la configuración de un servidor de base de datos sql server, dejo este pequeño recordatorio sobre la configuración necesaria para no tener inconvenietes al grabar fechas desde una aplicación desarrollada en C# .NET

Las fechas, tienen el formato Español – Argentina: dd/mm/aaaa con la hora seteada en HH:mm:ss (sin el am o pm)

Es muy común obtener un error como este al intentar grabar una fecha:

The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.

Para evitar estos inconvenientes, verificar lo siguiente:

1) En el servidor, utilizando el SQL Server Management Studio, vamos a Seguridad –> Inicios de Sesión y verificamos que el usuario con que estamos conectando a la base de datos, tenga como idioma predeterminado spanish.

2) En el servidor, donde se aloja la base de datos, configuramos en Panel de Control –> Configuración Regional y de Idioma: Español – > Argentina

2) En la maquina cliente, configuramos en Panel de Control –> Configuración Regional y de Idioma: Español – > Argentina

3) Verifiquemos que la cadena de conexión de nuestra aplicación utilice ese usuario.