martes, 24 de abril de 2012

Respaldos de Bases de Datos Automaticamente en la nube


Les dejo un tip para respaldos automáticos con almacenamiento en la nube, se puede hacer y de hecho hay herramientas mas profesionales para esta tarea o quiza usando el mismo SQL Server para crear los backups, pero esta me ha parecido sencilla y la uso desde hace 1 año y todo ha marcho bien.


Pasos:

1.-Descargar la herramienta. http://sqlbackupandftp.com/
2.-Instalarla en el servidor donde estan las bases de datos que requerimos respaldar



3.-Ahi configuramos ciertas caracteristicas, ademas seleccionamos las bases de datos (lado izquierdo) que necesitamos respaldar (creo que en la version free tiene un numero máximo de bases) Tambien podemos configurar nuesto correo electrónico para que nos notifique del proceso de respaldo.







4.- Damos clic donde dice advanced schedule nos aparecerá la siguiente ventana

Ahi tenemos que configurar la frecuencia de nuestros respaldos, en la parte superior nos muestra algunos scenarios de respaldos, Maniac podria ser el mejor en todo caso jejeje :D.




Les recomiendo que elijan windows task scheduler default, probe el otro (service) y a veces cuando tu servidor tiene ke ser reiniciado, este servicio no se inicia de manera automatica y comenzamos con problemas.

Una vez realizado todos estos pasos nuestro servicio de respaldo ya esta casi listo, salvo que nos falta almacenarlo en la nube.



 5.-Para este paso utilizaremos Dropbox. ahi con unos secillos pasos creamos una cuenta en dropbox y leemos o vemos el pequeño tutorial para q tengamos una idea de que es (si es k no lo has probado)

6.-Instalamos dropbox en el servidor, nos crea una carpeta especial donde podemos subir archivos y estos estaran en automatico en la nube claro tras un upload y esto tarda dependiendo del volumen del archivo. (no profundizo porque no es tema de esta entrada, si lo requieren posteen y con mucho gusto hago un pequeño tuto)

7.-Ahora tenemos que redireccionar la ruta donde queremos guardar elarchivo de backup que genera "sqlbackupandftp"




 y listo ya tendremos un sencillo backup en la nube.

¿Me preguntarán elias y cual es la ventaja? es seguro?

La gran ventaja que veo es ke uno nunca sabe cuando va haber una catastrofe informática, ni si los de soporte estan haciendo backups (mirrors) del servidor de manera periodica y tambien nosotros no estamos bajando los backups ke se hagan diario a un almacenamiento fuera del server, asi ke con esto nos podemos desantender un poco y solo inspeccionar ke se realicen, en caso ke el server reviente, nosotros estamos trnakilos porke tenemos un respaldo en internet (nube) que podemos descargar y montar en un server alterno.

Dropbox es para mi una herramienta poderosa para los informáticos y tambien para el publico en general, y esta es una de las muchas ventajas que nos brinda dropbox. Con respecto a la seguridad, pues considero que es mucho mas facil que vulneren nuestros servidores que los de dropbox, es tan seguro como el acceso a nuesto correo electrónico. :D

Espero les sirva, cualquier comentario o duda, por favor comenten, los espero. Saludos.





Procedimiento para enviar correos electrónicos desde la misma Base de Datos


CREATE     PROCEDURE [dbo].[sp_sendEmail]
(
    @cfgSMTPServer varchar(100),
    @cfgMail varchar(100),
    @cfgPwd varchar(100),
    @cfgPort varchar(5),
    @De varchar(100) ,
    @Para varchar(8000) ,
    @Titulo varchar(100)=" ",
    @Mensaje varchar(8000) =" ",
    @Attachment VARCHAR(1000) = " ",
    @Query VARCHAR(8000)= " "
)
AS
    set @De = 'Aqui va el titulo por default'
    Declare @Correo int
    Declare @proc int
    Declare @Dir varchar(500)
    Declare @DirUse varchar(500)
   
    SET @Dir = 'Configuration.fields("'
    SET @Dir = @Dir + 'http://schemas.microsoft.com/'
    SET @Dir = @Dir + 'cdo/configuration/'
   
    EXEC @proc = sp_OACreate 'CDO.Message', @Correo OUT
    SET @DirUse = @Dir + 'sendusing").Value'
    EXEC @proc = sp_OASetProperty @Correo, @DirUse,'2'
   

    if @proc <> 0
    begin
        print 'error'
    end
    --Servidor SMTP
   
    SET @DirUse = @Dir + 'smtpserver'+'").Value'
    EXEC @proc = sp_OASetProperty @Correo, @DirUse, @cfgSMTPServer
   
    if @proc <> 0
    begin
        RAISERROR('Error enviando correo 1',15,1)
        RETURN
    end
    -- Puerto normalmente el 25
    SET @DirUse = @Dir + 'smtpserverport").Value'
    EXEC @proc = sp_OASetProperty @Correo, @DirUse, @cfgPort
   
    if @proc <> 0
    begin
        RAISERROR('Error enviando correo 2',15,1)
        RETURN
    end
    -- Autenticacion, para usar cuenta y contraeña
   
    SET @DirUse = @Dir + 'smtpauthenticate").Value'
    EXEC @proc = sp_OASetProperty @Correo, @DirUse, '1'


    -- Cuenta
    SET @DirUse = @Dir + 'sendusername").Value'
    EXEC @proc = sp_OASetProperty @Correo, @DirUse, @cfgMail
   
    -- Contraseña
   
    SET @DirUse = @Dir + 'sendpassword").Value'
    EXEC @proc = sp_OASetProperty @Correo, @DirUse, @cfgPwd
   
    if @proc <> 0
    begin
        RAISERROR('Error enviando correo 3',15,1)
        RETURN
    end
    -- Autenticac
    -- Adjuntar Archivo
    CREATE TABLE #FileExists (FileExists int, FileIsDir int, ParentDirExists int)
   
    IF @Attachment <> ' '
    BEGIN
        declare @lcContAttach int
        set @lcContAttach = 0
        declare @StrEnd INT
        DECLARE @lcAttach VARCHAR(100)
        WHILE isnull(len(@Attachment),0) > 0
        BEGIN
            SELECT @StrEnd = CASE charindex(';', @Attachment)
                    WHEN 0 THEN len(@Attachment)
                    ELSE charindex(';', @Attachment) - 1
                    END
            SELECT @lcAttach = substring(@Attachment, 1, @StrEnd)
            SELECT @Attachment = substring(@Attachment, @StrEnd+2, len(@Attachment))
       

           
            DELETE #FileExists
            INSERT #FileExists
            EXEC master..xp_fileexist @lcAttach
           
            IF NOT EXISTS (SELECT * FROM #FileExists WHERE FileExists = 1)
            BEGIN
                RAISERROR ('El archivo no existe.', 16, 1,@lcAttach)
                RETURN 1
            END
           
            EXEC @proc = sp_OAMethod @Correo, 'AddAttachment', NULL, @lcAttach
            IF @proc <> 0
            BEGIN
                SET @lcContAttach = @lcContAttach + 1
            ENd

        END
        PRINT 'Archivo(s) adjuntado(s): ' +LTRIM(RTRIM(str(@lcContAttach)))
    END
    --Fin adjuntar Archivo
   
    --Consulta HTML
    if @Query <> ' '
    begin
        declare @Columns varchar(8000)
           declare @ColHeader varchar(8000)
           Declare @SqlCmd varchar(8000)
           Declare @HTMLBody varchar(8000)
        -- drop temporary tables used.
        IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE name = '##TEMPhtml1')
        DROP TABLE ##TEMPhtml1
        IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE name = '##TEMPhtml2')
        DROP TABLE ##TEMPhtml2
       
        -- prepare query
        set @SqlCmd = 'select * into ##tempHTML1 from (' + @Query + ') as t1'
        execute (@SqlCmd)
       
        --Prepare columns details
        SELECT @columns =
            COALESCE(@columns + ' + ''</td><td>'' + ', '') +
            'RTrim(convert(varchar(100),isnull(' + column_name +','' '')))'
            FROM tempdb.information_schema.columns
            where table_name='##tempHTML1'
           
        --Prepare column Header
        set @colHeader = '<tr bgcolor=#FAAC58 align=Left>'
        SELECT @colHeader = @colHeader + '<td><b>' + column_name + '</b></td>'
        FROM tempdb.information_schema.columns where table_name='##tempHTML1'
        set @colHeader=@colHeader + '</tr>'
       
        --prepare final output
        set @SqlCmd =
            'Select ''<tr><td>'' + ' +
            @columns +
            ' ''</td></tr> '' into ##tempHTML2 from ##tempHTML1 '
        execute( @SqlCmd)
           
        --set @finalhtmlout=
        set @HtmlBody =
            ' <html> <body><style type="text/css" media="all"> ' +
            'table { margin-bottom: 2em; border-collapse: collapse } ' +
            'td,th {border= 1 solid #999; padding: 0.2em 0.2em; font-size: 12;} ' +
            '</style> <table width="100%"> ' +
            @colHeader
       
        select @HtmlBody = @HtmlBody + [</td></tr>]
        from ##tempHTML2
       
        set @HtmlBody = @HtmlBody + ' </table></body></htmL>'
   
        --EXEC @proc = sp_OASetProperty @Correo, 'HTMLBody',  @HtmlBody
        set @Mensaje = @HtmlBody
        -- drop temporary tables used.
        IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE name = '##TEMPhtml1')
        DROP TABLE ##TEMPhtml1
        IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE name = '##TEMPhtml2')
        DROP TABLE ##TEMPhtml2   
    end
    --Fin Consulta
   
    -- Con esto grabas la configuracion
    EXEC @proc = sp_OAMethod @Correo, 'Configuration.Fields.Update', null
   
   
    -- Metes los parametros
    EXEC @proc = sp_OASetProperty @Correo, 'To', @Para
    EXEC @proc = sp_OASetProperty @Correo, 'From', @De
    EXEC @proc = sp_OASetProperty @Correo, 'Subject', @Titulo
   
    if @proc <> 0
    begin
        RAISERROR('Error enviando correo 4',15,1)
        RETURN
    end
    -- Autenticac
    -- Puedes usar 'HTMLBody' o 'Textbody'
   
    EXEC @proc = sp_OASetProperty @Correo, 'HTMLBody', @Mensaje
   
    if (@proc <> 0 )
    begin
        RAISERROR('Error enviando correo HTML',15,1)
        RETURN
    end
    -- Autenticac
    -- Aqui mandas el mensaje
    EXEC @proc = sp_OAMethod @Correo, 'send',NULL
   
    -- Por si hay error
    Declare @iMsg int
    Declare @hr int
    Declare @source varchar(255)
    Declare @description varchar(500)
    Declare @output varchar(1000)
    IF ( @proc <> 0 )
    BEGIN
        IF @proc <>0
        BEGIN
            EXEC @proc = sp_OAGetErrorInfo NULL, @source OUT, @description OUT
            IF @proc = 0
            BEGIN
                SELECT @output = ' Source: ' + @source
                PRINT @output
                SELECT @output = ' Description: ' + @description
                PRINT @output
            END
            ELSE
            BEGIN
                PRINT ' sp_OAGetErrorInfo failed.'
                RETURN
            END
        END
    -- Limpia el objeto
        EXEC @proc = sp_OADestroy @Correo
        RAISERROR('Error enviando correo last',15,1)
        RETURN
    END
   
    PRINT 'Correo enviado satisfactoriamente'
    -- Limpia el objeto
    EXEC @proc = sp_OADestroy @Correo

/*
Es necesario crear este procedimiento en la base de datos
master . Ejemplo de implementación:

exec master.dbo.sp_sendEmail
            @cfgSMTPServer = 'correoweb.misupercito.com.mx',
            @cfgMail = 'correo@misupercito.com.mx', --Este correo es el emisor
            @cfgPwd = 'tupass',
            @cfgPort = '25', --Este es el puerto normalmente usado
            @De = 'saig.dap@campeche.gob.mx', --Es lo que aparecera como emisor, puede ser dif al @cfgMail
            @Para=@lcMails,-- Correo Receptor (Clientes, empleados etc..)
            @Titulo = 'Felicidades por tu cumpleaños', '' --Titulo del mensje
            @mensaje = @lcMSG,-- 'Mensaje'
            @Attachment = ' ',--Sin hay archivos adjuntos
            @Query ='select * from midb.dbo.mitabla'--Si deseas enviar una consulta, ten en cuenta que se ejecuta el store en Master
 Puedes costumizarlo a tu gusto...
*/

jueves, 19 de abril de 2012

Consultar varios LIKE´s sin SQL Dinámico

--Creamos una tabla temporal para la prueba
Declare @vTable TABLE(id INT, NAME VARCHAR(100))
INSERT INTO @vTable
SELECT 1,'Jose' UNION ALL
SELECT 2,'Gabriel' UNION ALL
SELECT 3,'Gabino' UNION ALL
SELECT 4,'Francisco'

DECLARE @vParam VARCHAR(100)
-- Aqui introducimos los valores separados por coma.
SET @vParam = 'Gab,Fran'

-- Utilizamos CROSS APPLY para completar esta tarea.
SELECT * FROM @vTable
CROSS APPLY (SELECT [item] FROM dbo.fnSplit(@vParam,',')) b
WHERE NAME LIKE '%' + b.[item] + '%'

/*
* La funcion dbo.fnSplit es muy común encontrarla en la
* red, pero se las dejo aqui para que la utilicen
* */

create FUNCTION [dbo].[fnSplit](
    @sInputList VARCHAR(8000) -- Lista de los valores separados
  , @sDelimiter VARCHAR(8000) = ',' -- Delimitador
) RETURNS @List TABLE (item VARCHAR(8000))

BEGIN
    DECLARE @sItem VARCHAR(8000)
    WHILE CHARINDEX(@sDelimiter,@sInputList,0) <> 0
     BEGIN
         SELECT
          @sItem=RTRIM(LTRIM(SUBSTRING(@sInputList,1,CHARINDEX(@sDelimiter,@sInputList,0)-1))),
          @sInputList=RTRIM(LTRIM(SUBSTRING(@sInputList,CHARINDEX(@sDelimiter,@sInputList,0)+LEN(@sDelimiter),LEN(@sInputList))))

         IF LEN(@sItem) > 0
          INSERT INTO @List SELECT @sItem
     END

    IF LEN(@sInputList) > 0
         INSERT INTO @List SELECT @sInputList -- Ultimo item
    RETURN
END

Hola Blogger

Esta será mi primera entrada en este blog, espero publicar pequeños articulos interesantes desde mi punto de vista, trucos del "dia a dia" en temas de programación, les comento que me apasiona SQL Server, por el momento trabajo con SQL Server 2008 R2, espero ser claro con mis entradas y que todo lo que se publique en este blog sea útil, tambien espero mucha retro-alimentación por parte de ustedes. Por cierto soy mexicano y me encanta las chelas!! :D