Mostrando las entradas con la etiqueta SQL Server. Mostrar todas las entradas
Mostrando las entradas con la etiqueta SQL Server. Mostrar todas las entradas

2017/04/03

SQL Server - Como ocultar una instancia

Por defecto cuando instalamos SQL Server nuestra instancia esta abierta y puede ser descubierta vía red, para demostrar esto simplemente abrimos un SSMS (SQL Server Management Studio) y vamos al browser de servidores SQL de nuestra red.
SQL Server - Como ocultar una instancia

Como se observa en la imagen al hacer un browser de servidores va a buscar en toda la red. todo SQL Server que este activo.
Para que esto no suceda lo que necesitamos hacer es configurar la instancia para que este en modo hide, para eso hacemos:
 - Accedemos al SQL Server configuration Manager.
 - Vamos a SQL Server Network Configuration.
 - Protocolos de SQL Server y hacemos clic del mouse sobre esa opción para ir a propiedades.
SQL Server - Como ocultar una instancia
 - Ponemos en Yes la opción de “Hide Instance”.
 - Reiniciamos el servicio.

Con esta configuración nuestra instancia queda mas segura ya que la misma no podrá ser browsiada a nivel red.

2017/03/15

SQL Server - Backup a todas las bases de datos

Las copias de seguridad de las bases de datos son muy importantes es por eso que se recomienda hacerlas periódicamente para no perder alguna información valiosa que estas contengan.

Ya sea que estés trabajando locamente o en un servidor hacerlo una a una puede ser tedioso y hasta aburrido, menos mal que SQL no da la facilidad de hacerlo vía Script y con un cursos podemos sacarle copia a todas nuestras bases de datos.

Para ello pueden usar este script:
DECLARE @name VARCHAR(50) -- Nombre de la base de datos  
DECLARE @path VARCHAR(256) -- Ruta de acceso para archivos de copia de seguridad
DECLARE @fileName VARCHAR(256) -- Nombre de archivo para copia de seguridad  
DECLARE @fileDate VARCHAR(20) -- Utilizado para el nombre de archivo
 
-- Especificar directorio de copia de seguridad de la base de datos
SET @path = 'C:\Backup\'  
 
-- Especificar el formato del nombre de archivo
SELECT @fileDate = CONVERT(VARCHAR(20) ,GETDATE() ,112) 
 
DECLARE db_cursor CURSOR  
FOR
    SELECT NAME
    FROM   MASTER.dbo.sysdatabases
    WHERE  NAME NOT IN ('master' ,'model' ,'msdb' ,'tempdb')  -- Excluir estas bases de datos
 
OPEN db_cursor   
FETCH NEXT FROM db_cursor INTO @name   
 
WHILE @@FETCH_STATUS=0
BEGIN
    SET @fileName = @path+@name+'_'+@fileDate+'.bak' 
    BACKUP DATABASE @name TO DISK=@fileName 
    
    FETCH NEXT FROM db_cursor INTO @name
END   

 
CLOSE db_cursor   
DEALLOCATE db_cursor

Fuente: https://www.mssqltips.com

2016/05/12

Obtener instancias de SQL Server y bases de datos disponibles desde C#

Por si alguna vez se te ha planteado la necesidad de mostrar un formulario con los orígenes de datos de SQL Server disponibles (algo como el formulario Agregar conexión de Visual Studio) voy a plantear un pequeño ejemplo.
Creamos un nuevo proyecto de Windows Forms al que llamaremos EDGAR_Group, y en él un formulario Form1 en el que añadimos 2 combobox: cmbServidores y cmbBasedeDatos.
En el código del formulario añadimos lo siguiente: 
using System;
using System.Data;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Data.Sql;
using System.Data.SqlClient;

namespace EDGAR_Group
{
    public partial class Form1 : Form
    {
        SqlDataSourceEnumerator servidores;
        DataTable tablaservidores;
        string servidor;

        public Form1()
        {
            InitializeComponent();
            servidores = SqlDataSourceEnumerator.Instance;
            tablaservidores = new DataTable();
        }        
    }
}
Ahora hay que añadir el código para el evento click de cada uno de los combobox:
Para obtener la lista de instancias de SQL Server disponibles usaremos el objeto SqlDataSourceEnumerator.Instance, concretamente el método GetDataSources() que nos devuelve un DataTable con las características de las instancias: nombre del servidor, nombre de instancia, si forma parte de un clúster y la versión (8.00.x para SQL Server 2000 y superiores):
private void cmbServidores_Click(object sender, EventArgs e)
{
    //Comprobamos que no se haya cargado ya el combobox
    if (tablaservidores.Rows.Count == 0)
    {
        // Obtenemos un dataTable con la información sobre las instancias visibles
        // de SQL Server 2000 y 2005
        tablaservidores = servidores.GetDataSources();


        // Creamos una lista para que sea el origen de datos del combobox
        List listaservidores = new List();
        
        // Recorremos el dataTable y añadimos un valor nuevo a la lista con cada fila
        foreach (DataRow rowServidor in tablaservidores.Rows)
        {
            // La instancia de SQL Server puede tener nombre de instancia 
            //o únicamente el nombre del servidor, comprobamos si hay 
            //nombre de instancia para mostrarlo
            if (String.IsNullOrEmpty(rowServidor["InstanceName"].ToString()))
                listaservidores.Add(rowServidor["ServerName"].ToString());
            else
                listaservidores.Add(rowServidor["ServerName"] + "\\" + rowServidor["InstanceName"]);
        }

        // Asignamos al origen de datos del combobox la lista con 
        // las instancias de servidores
        cmbServidores.DataSource = listaservidores;
    }
}

Y para que nos muestre las bases de datos tenemos que ejecutar una consulta sobre la vista sys.databases:
private void cmbBasedeDatos_Click(object sender, EventArgs e)
{
    string select;
    string cadenaConexion;
    List listaBasesdatos = new List();

    servidor = this.cmbServidores.Text;

    // Componemos la cadena de conexión con el servidor seleccionado 
    // con seguridad integrada
    // Si se conecta con usuario de SQL Server hay que cambiar 
    // la cadena de conexión
    cadenaConexion = "Data Source=" + servidor + ";Integrated Security=True;Initial Catalog=master";

    using (SqlConnection con = new SqlConnection(cadenaConexion))
    {
        // Abrimos la conexión
        con.Open();

        // Obtenemos los nombres de las bases de datos que haya en el servidor
        // se pueden filtrar para no mostrar las bases de datos de sistema
        select = "select name from sys.databases;";

        // Obtenemos un dataReader con el resultado
        SqlCommand com = new SqlCommand(select, con);
        SqlDataReader dr = com.ExecuteReader();

        // Recorremos el dataReader y añadimos un elemento nuevo 
        // por cada registro
        while (dr.Read())
        {
            listaBasesdatos.Add(dr[0].ToString());
        }

        // Asignamos la lista de bases de datos como origen de datos del combobox
        cmbBasedeDatos.DataSource = listaBasesdatos;
    }
}

Y ya está, con esto tenemos un formulario que permite seleccionar la instancia de SQL Server y la base de datos al que nos queremos conectar.
Si en vez de seguridad integrada usamos un usuario y password de SQL Server sólo hay que cambiar la cadena de conexión.

Puedes descargar el proyecto aqui

2016/02/14

SQL - Convertir fecha a char en varios formatos

Convertir fecha a char en varios formatos

Las fechas son un tipo de datos muy usado, sin embargo a veces tenemos varias veces tenemos tantos códigos en la cabeza que una conversión de fechas lo dejamos para el internet (al menos eso hago yo) así que para que tengas algunos formatos, la próxima vez que desees convertir una fecha a char puedes revisar alguna de estas opciones, claro que deberás reemplazar el “CURRENT_TIMESTAMP” por la variable o fecha deseada.
Al costado colocado como comentario se encuentra la forma resultante, así que espero les sea de ayuda.
/*
 * CONVERTIR FECHA EN CHAR
 */
SELECT  CONVERT(CHAR(10), CURRENT_TIMESTAMP, 23) --AAAA-MM-DD
SELECT  CONVERT(CHAR(10), CURRENT_TIMESTAMP, 101) --MM/DD/AAAA
SELECT  CONVERT(CHAR(10), CURRENT_TIMESTAMP, 102) --AAAA.MM.DD
SELECT  CONVERT(CHAR(10), CURRENT_TIMESTAMP, 103) --DD/MM/AAAA
SELECT  CONVERT(CHAR(10), CURRENT_TIMESTAMP, 104) --DD.MM.AAAA
SELECT  CONVERT(CHAR(10), CURRENT_TIMESTAMP, 105) --DD-MM-AAAA
SELECT  CONVERT(CHAR(10), CURRENT_TIMESTAMP, 110) --MM-DD-AAAA
SELECT  CONVERT(CHAR(10), CURRENT_TIMESTAMP, 111) --AAAA/MM/DD
SELECT  CONVERT(CHAR(8), CURRENT_TIMESTAMP, 112) --AAAAMMDD

SELECT  CONVERT(CHAR(19), CURRENT_TIMESTAMP, 20) --AAAA-MM-DD HH:MM:SS (H 1-24)
SELECT  CONVERT(CHAR(23), CURRENT_TIMESTAMP, 21) --AAAA-MM-DD HH:MM:SS.MSS (H 1-24)
SELECT  CONVERT(CHAR(23), CURRENT_TIMESTAMP, 25) --AAAA-MM-DD HH:MM:SS.MSS (H 1-24)
SELECT  CONVERT(CHAR(19), CURRENT_TIMESTAMP, 120) --AAAA-MM-DD HH:MM:SS (H 1-24)
SELECT  CONVERT(CHAR(23), CURRENT_TIMESTAMP, 121) --AAAA-MM-DD HH:MM:SS.MSS (H 1-24)
SELECT  CONVERT(CHAR(23), CURRENT_TIMESTAMP, 126) --AAAA-MM-DD?HH:MM:SS.MSS (H 1-24)

SELECT  CONVERT(CHAR(8), CURRENT_TIMESTAMP, 1) --MM/DD/AA
SELECT  CONVERT(CHAR(8), CURRENT_TIMESTAMP, 2) --AA.MM.DD
SELECT  CONVERT(CHAR(8), CURRENT_TIMESTAMP, 3) --DD/MM/AA
SELECT  CONVERT(CHAR(8), CURRENT_TIMESTAMP, 4) --DD.MM.AA
SELECT  CONVERT(CHAR(8), CURRENT_TIMESTAMP, 5) --DD-MM-AA
SELECT  CONVERT(CHAR(8), CURRENT_TIMESTAMP, 10) --MM-DD-AA
SELECT  CONVERT(CHAR(8), CURRENT_TIMESTAMP, 11) --AA/MM/DD
SELECT  CONVERT(CHAR(6), CURRENT_TIMESTAMP, 12) --AAMMDD
SELECT  CONVERT(CHAR(20), CURRENT_TIMESTAMP, 22) --MM/DD/AA H:MM:SS (H 1-12)

SELECT  CONVERT(CHAR(19), CURRENT_TIMESTAMP, 0)  --Mes DD AAAA h:mmPM (H 1-12)
SELECT  CONVERT(CHAR(9), CURRENT_TIMESTAMP, 6) --DD mes AA
SELECT  CONVERT(CHAR(10), CURRENT_TIMESTAMP, 7) --mes DD, AA
SELECT  CONVERT(CHAR(26), CURRENT_TIMESTAMP, 9) --Mes DD AAAA H:MM:SS:MSS (H 1-12)
SELECT  CONVERT(CHAR(24), CURRENT_TIMESTAMP, 13) --DD MES AAAA HH:MM:SS:MSS (H 1-24)
SELECT  CONVERT(CHAR(26), CURRENT_TIMESTAMP, 109) --MES DD AAAA H:MM:SS:MSS (H 1-12)
SELECT  CONVERT(CHAR(19), CURRENT_TIMESTAMP, 100) --MES DD AAAA H:MM (H 1-12)
SELECT  CONVERT(CHAR(11), CURRENT_TIMESTAMP, 106) --DD MES AAAA
SELECT  CONVERT(CHAR(12), CURRENT_TIMESTAMP, 107) --MES DD,AAAA
SELECT  CONVERT(CHAR(24), CURRENT_TIMESTAMP, 113) --DD MES AAAA HH:MM:SS:MSS (H 1-24)

SELECT  CONVERT(CHAR(8), CURRENT_TIMESTAMP, 8 ) --HH:MM:SS (H 1-24)
SELECT  CONVERT(CHAR(12), CURRENT_TIMESTAMP, 14) --HH:MM:SS:MSS (H 1-24)
SELECT  CONVERT(CHAR(8), CURRENT_TIMESTAMP, 24) --HH:MM:SS (H 1-24)
SELECT  CONVERT(CHAR(8), CURRENT_TIMESTAMP, 108) --HH:MM:SS (H 1-24)
SELECT  CONVERT(CHAR(12), CURRENT_TIMESTAMP, 114) --HH:MM:SS:MSS (H 1-24)

2015/11/06

SQL Server - Quién esta conectado a la base de datos y desconectar

1. Si usted quiere saber que usuarios tienen conexiones abiertas en una base de datos, puede incluir cláusula WHERE dbid = db_id ('AdventureWorks2012').

2. Debe tener cuidado y excluir su propia conexión por ejemplo, y spid <> 55 (mi id de conexión).

3. Ejemplo:
DECLARE @kill VARCHAR(8000)='';
SELECT @kill = @kill+'kill '+CONVERT(VARCHAR(5) ,spid)+';'
FROM   MASTER..sysprocesses
WHERE  dbid = DB_ID('AdventureWorks2012')
       AND spid<>55

PRINT @kill

EXEC (@kill);

2015/10/01

SQL - Lista de procedimientos almacenados modificados en los últimos 7 días

Este sencillo script ayuda a identificar los procedimientos almacenados que se han cambiado / modificado en los últimos 7 días.
SELECT *
FROM   sys.objects
WHERE  TYPE = 'P'
       AND DATEDIFF(D ,modify_date ,GETDATE())<7

2015/07/09

SQL - Conocer las ultimas consultas ejecutadas

El siguiente script permite saber que consultas se acaban de ejecutar en la base de datos.
SELECT deqs.last_execution_time  AS [Time],
       dest.TEXT                 AS [Query]
FROM   sys.dm_exec_query_stats   AS deqs
       CROSS APPLY sys.dm_exec_sql_text(deqs.sql_handle) AS dest
ORDER BY
       deqs.last_execution_time DESC
La gracia de la consulta es justamente  esa, listar las ultimas consultas SQL que se han ejecutado.

SQL - Vaciar los registros de distintas tablas en una base de datos

Vamos a recorrer todas las tablas de nuestra base de datos y eliminar sus registros. Para ello, utilizaremos la información que nos brinda information_schema.tables. Es muy importante que limitemos de alguna forma las tablas que se van a vaciar, por ejemplo, si las tablas de nuestra aplicación empiezan por "TBL_" podríamos especificar una condición WHERE que filtre por aquellas tablas que empiezan con ese nombre.
USE DB_PRUEBA
 
DECLARE @SQL_DELETE     VARCHAR(255),
        @NOM_TABLA      VARCHAR(255)

DECLARE CURSOR_DELETE CURSOR  
FOR
    SELECT 'DELETE FROM ' + TABLE_SCHEMA + '.' + TABLE_NAME,
           TABLE_SCHEMA + '.' + TABLE_NAME
    FROM   information_schema.tables
    WHERE  TABLE_NAME NOT LIKE 'sysdiagrams'
    ORDER BY
           TABLE_NAME

OPEN CURSOR_DELETE FETCH NEXT FROM CURSOR_DELETE INTO @SQL_DELETE, @NOM_TABLA
WHILE @@FETCH_STATUS = 0
BEGIN
    EXEC (@SQL_DELETE)
    FETCH NEXT FROM CURSOR_DELETE INTO @SQL_DELETE, @NOM_TABLA
END
CLOSE CURSOR_DELETE
DEALLOCATE CURSOR_DELETE

2015/06/01

SQL Server - Utilizando Arrays de parametros en Procedimientos Almacenados

Una característica muy solicitada por los desarrolladores en SQL Server es la de poder pasar varios valores a un procedimiento almacenado en forma de array. Desde hace mucho tiempo utilizo una función de SQL que me permitía trabajar con Arrays a través de una cadena de texto delimitada por comas, normalmente los utilizaba en procesos de selección como en el ejemplo siguiente:
CREATE PROCEDURE SP_GetPerson
 @param VARCHAR(MAX)
AS
 SELECT p.BusinessEntityID,
        p.FirstName,
        p.LastName
 FROM   Person.Person p
 WHERE  p.BusinessEntityID IN (SELECT *
                               FROM   [dbo].[ArrayToTable] (@param))
 ORDER BY
        p.BusinessEntityID ASC
En este procedimiento el parametro @param recibe una cadena delimitada por comas con los valores '1,2,3,4,5', el SP_GetPerson devuelve todas las personas con estos códigos, la definición del parametro '@param' se realiza con varchar(MAX), para que la cadena pueda almacenar la mayor cantidad de códigos posible, sin embargo varchar(MAX) tiene la limitación de 8000 caracteres y en algunas situaciones se nos puede quedar pequeño.
La definición de la función en Transact-Sql es la siguiente:
CREATE FUNCTION [dbo].[ArrayToTable]
(
 @delimStr NVARCHAR(MAX)
)
RETURNS @StrValTable TABLE 
        (StrVal VARCHAR(20))
AS
BEGIN
 DECLARE @strlist     NVARCHAR(MAX),
         @pos         INT,
         @delim       CHAR,
         @lstr        NVARCHAR(MAX)
 
 SET @strlist = ISNULL(@delimStr, '')
 SET @delim = ','
 
 WHILE ((LEN(@strlist) > 0) AND (@strlist <> ''))
 BEGIN
     SET @pos = CHARINDEX(@delim, @strlist)
     
     IF @pos > 0
     BEGIN
         SET @lstr = SUBSTRING(@strlist, 1, @pos -1)
         SET @strlist = LTRIM(SUBSTRING(@strlist, CHARINDEX(@delim, @strlist) + 1, 8000))
     END
     ELSE
     BEGIN
         SET @lstr = @strlist
         SET @strlist = ''
     END
     
     INSERT @StrValTable
     VALUES
       (
         @lstr
       )
 END
 RETURN
END
GO
Básicamente lo que hace es crear una tabla temporal conformada por un campo y cada valor en un único registro, de esta forma la consulta de arriba puede ser ejecutada sin problemas, hay que tener en cuenta que el uso de tablas temporales puede reducir el rendimiento, sin embargo es mejor esto a llamar al SP muchas veces. Podriamos tambien optar por pasar los arrays con XML y readaptar la función.

2015/05/16

SQL Server - Convertir o separar por comas una cadena dividido en filas

La siguiente función convierte y separa comas una cadena dividido en filas.
DECLARE @nombre_db AS VARCHAR(50) 
CREATE FUNCTION fn_SplitString
(
 @Str           NVARCHAR(MAX),
 @Separator     CHAR(1)
)
RETURNS @ResultOutput TABLE(Id INT IDENTITY(1, 1), Result NVARCHAR(100))
AS
BEGIN
 DECLARE @Splitted_string NVARCHAR(4000)
 DECLARE @Pos INT
 DECLARE @NextPos INT
 
 SET @Str = @Str + @Separator
 SET @Pos = CHARINDEX(@Separator, @Str)
 WHILE (@pos <> 0)
 BEGIN
     SET @Splitted_string = SUBSTRING(@Str, 1, @Pos - 1)
     SET @Str = SUBSTRING(@Str, @pos + 1, LEN(@Str))
     SET @pos = CHARINDEX(@Separator, @Str)
     INSERT INTO @ResultOutput
     VALUES
       (
         @Splitted_string
       )
 END
 RETURN
END
Utilizando la función fn_SplitString en consulta:
--Separar una cadena por comas
SELECT Result
FROM   fn_SplitString('Split,string,example,in,sql,server', ',')

--Separar una cadena por símbolo de canalización
SELECT Result
FROM   fn_SplitString('Split|string|example|in|sql|server', '|')

--Separar una cadena por el espacio
SELECT Result
FROM   fn_SplitString('Split string example in sql server', ' ')

2015/05/02

SQL Server - Backup a todas las bases de datos

Aqui les dejo el código para hacer backup de todas sus bases de datos, solo tienen que ponerlo en un trabajo(jobs) para que se ejecute periódicamente.
DECLARE @nombre_db AS VARCHAR(50) 
DECLARE tablas_cursor CURSOR  
FOR
    SELECT NAME
    FROM   sys.databases
    WHERE  NAME NOT IN ('master' ,'tempdb' ,'model' ,'msdb')

OPEN tablas_cursor 

FETCH NEXT FROM tablas_cursor INTO @nombre_db 

WHILE @@fetch_status=0
BEGIN
    DECLARE @nombre VARCHAR(150) 
    
    SET @nombre = CONVERT(VARCHAR(9) ,GETDATE() ,6) 
    SET @nombre = 'D:\Backup\'+@nombre+'-' 
       +@nombre_db+'.bak'
    
    SET @nombre = REPLACE(@nombre ,' ' ,'') 
    
    
    BACKUP DATABASE @nombre_db TO DISK=@nombre WITH COMPRESSION
    
    FETCH NEXT FROM tablas_cursor INTO @nombre_db
END 

CLOSE tablas_cursor 

DEALLOCATE tablas_cursor

2015/01/08

SQL SERVER - Encontrar tablas creadas o modificadas en la última semana

El siguiente Script SQL muestra una manera de identificar las tablas que se crearon o modificaron en la base de datos en la ultima semana.
 
SELECT o.name AS [Object_Name]
      ,s.name [Schema_Name]
      ,o.type_desc [Description]
      ,o.create_date [Creation_Date]
      ,o.modify_date [Modified_Date]
FROM   sys.all_objects o
       LEFT OUTER JOIN sys.schemas s
            ON  o.schema_id = s.schema_id
WHERE  create_date>(GETDATE()- 7)
       OR modify_date>(GETDATE()- 7)


Como puede ver, la consulta se puede agregar a un Job de SQL Server y podemos enviar el mismo como un correo electrónico al DBA o equipo de seguridad de forma automática.

2014/12/30

Cómo elegir una Base de Datos para su Empresa


A medida que su organización recopila más datos y quiere hacer un mejor uso de los datos que va adquiriendo se tienen varias opciones que van mucho más allá de las bases de datos tradicionales. Quizás ud. se encuentra en el punto en que el uso de herramientas de inteligencia de negocios que hacen extracciones desde su datawarehouse no es  suficiente, y los datos son demasiado grandes para analizarlos lo suficientemente rápido por los medios tradicionales, y por lo tanto, es el momento de realizar un análisis detallado de las alternativas de bases de datos disponibles en el mercado.

Claramente la elección de la tecnología de base de datos estará determinada por los parámetros de su proyecto: la cantidad de datos, la rapidez con que le llegan, el análisis que quiere hacer y si va a utilizarlos operacionalmente o para la toma de decisiones estratégicas. También es posible que desee extraer conocimiento del negocio, por ejemplo, de la venta al detalle en el punto de venta o de las transacciones de un programa de CRM. Quizás usted podría estar tratando de acelerar la logística, identificar dónde está el inventario en tiempo real en su cadena de suministro o realizar un seguimiento del comportamiento de un gran número de clientes en su sitio web.

La pregunta es entonces: ¿Cuáles bases de datos son apropiadas para determinados tipos de proyectos?. La siguiente breve guía que hemos elaborado, puede ayudarle a evaluar las opciones que hay disponibles:

Base de datos relacional

Qué es: Es el sistema tradicional de base de datos relacional, con datos estructurados organizados en tablas.
Fortalezas: Usa el lenguaje estándar de consulta SQL, que  garantiza la consistencia de los resultados de las consultas.
Debilidades: Requiere que la tabla completa se almacene en archivo o memoria, requiere de datos estructurados y esquemas relacionales, la tabla canónica debe ser replicada con el fin de realizar análisis en servidores paralelos.

Si usted está tratando con datos estructurados o de transacciones relativamente simples, por ejemplo, pedidos de clientes o datos de puntos de venta y desea la máxima flexibilidad en las preguntas que quiere responder, el lugar para comenzar es la base de datos relacional. La ventaja directa es que su organización probablemente ya está utilizando un RDBMS, por lo que su personal de TI,  incluyendo los analistas de bases de datos, pueden crear las consultas SQL directamente sin necesidad de mayor entrenamiento. Usted sólo tiene que elegir una base de datos de clase empresarial (a la escala adecuada de su proyecto) para satisfacer sus necesidades de análisis de datos. Puede elegir algunas tales como Oracle, IBM InfoSphere Warehouse, Sybase o Teradata. Hay muchas más, éstas son sólo un ejemplo.

Por otro lado, las desventajas podrian estar en el precio, en la flexibilidad de las consultas a datos que están rigurosamente estructurados y que se almacenan en un único conjunto canónico de tablas, las cuales tienen que ser replicadas si necesitar usar el procesamiento en paralelo para acelerar el rendimiento. En este caso, cada actualización tiene que ser replicada en otras copias, así que si los datos cambian mucho, hay un montón de costos asociados (procesamiento en memoria, procesamiento en disco, equipos, discos,  tiempo, etc.), lo que afectará negativamente a los tiempos de respuesta de las consultas. Usted podría también mantener las tablas en memoria en lugar de tenerlas en el disco, con el fin de acelerar la lectura y escritura, pero esto tiene un costo mayor. Y a medida que crecen los datos, el tiempo de respuesta para las consultas de análisis pueden fácilmente pasar de ser instantáneas a tomar horas, días o semanas.

Base de datos columnar

Qué es: Es una base de datos relacional que almacena los datos por columna en lugar de filas.
Fortalezas: Todos los puntos fuertes de una base de datos relacional, optimizada para un mejor rendimiento en el análisis de los datos de varias columnas a la vez.
Debilidades: Requiere que la tabla completa se almacene en archivo o memoria, requiere de datos estructurados y esquemas relacionales.

¿Qué pasa si sus datos están muy estructurados, pero necesita realizar un mayor análisis de los datos almacenados en unas pocas columnas particulares, por ejemplo, el análisis de las transacciones de venta por tienda o por producto?. En este caso, una base de datos en columnas tiene más sentido, y puede elegir algunas de las opciones tales como Sybase IQ, Microsoft SQL Server 2012, Teradata Columnar o Actian VectorWise.

Aunque suena raro el nombre, una base de datos columnar es también una base de datos relacional. La diferencia está en la forma: en lugar de almacenar cada tabla de datos como una fila tras otra en un solo archivo, una base de datos columnar almacena las columnas en archivos separados, por lo que se pueden indexar y buscar por separado, incluso en diferentes servidores (en un clúster) para mejorar el rendimiento. Como resultado, las bases de datos columnares pueden ser mucho más rápidas para el análisis que una base de datos relacional tradicional, ya que lo concentran en sólo una o unas pocas columnas. A pesar de esta ventaja, este tipo de base también hereda muchos inconvenientes de las bases de datos relacionales, incluyendo el esfuerzo y el tiempo de procesamiento del sistema necesario para mantener las tablas canónicas.

Bases de datos NoSQL

Qué es: Es una base de datos no-relacional que almacena los datos en registros de transacciones en lugar de las tablas.
Fortalezas: Más rápido y más compacto cuando se trata de bases de datos muy grandes, soporta datos no estructurados o estructurados irregularmente, es compatible con el análisis y fácil de distribuir a servidores en paralelo.
Debilidades: La tecnología no está madura, no hay un lenguaje de consulta estándar o herramientas de consulta, no garantiza la consistencia en los resultados de las consultas.

Supongamos ahora que su proyecto se ocupará de un orden de magnitud superior datos, por decir Teras de información, que no están tan estructurados. Por ejemplo, el seguimiento de la logística del inventario en tiempo real o el análisis de cómo los clientes utilizan su sitio web. Con bases de datos convencionales, se podría requerir de grandes tablas multidimensionales en los que la mayor parte de las celdas probablemente estarían vacías, mientras que otras, podrían tener que almacenar varios valores a la vez. Este es el tipo de situación complicada es por la que las bases de datos NoSQL fueron creadas. Estas incluyen bases de datos NoSQL como Hadoop HBase, Hypertable, MongoDB o MarkLogic. Con NoSQL, no hay una tabla real de datos, no hay estructura física de una tabla. Aquí, en cambio, la base de datos consiste en una lista de todos los datos (que puede contener una información con diferente forma cada vez) , que se escriben, haciendo una consulta de búsqueda que lista para saber qué datos se han escrito recientemente en un registro en particular. Es como si se ha creado una enorme tabla que en cada escritura, agrega la información y estira la tabla al terminar la búsqueda en el registro.

Con NoSQL no hay necesidad de una tabla gigante canónica que se almacene en el disco o en la memoria. Los registros individuales no se escriben en una tabla, sino que se almacenan en estructuras de datos complejas en un sólo archivo o documento, como por ejemplo, almacenar la información sobre una publicación de un blog (título, cuerpo de texto, autor, etc.) junto a los comentarios y etiquetas del mismo, ¡todo en un único registro!. Y las copias de la base de datos NoSQL se pueden escribir en varios servidores dentro de un grupo, por lo que el análisis se puede dividir en paralelo. En comparación con las tablas de datos convencionales, NoSQL recorre un camino más pequeño, se realiza mucho más rápido y es más fácil de poner en paralelo. Sin embargo, como su nombre lo indica, NoSQL no ofrece garantías de integridad relacional o consistencia de datos, y en la actualidad no hay lenguaje de consulta estándar que facilite su consulta. Este tipo de bases de datos es más adecuada para el análisis de grandes volúmenes de datos (conocido en la jerga actual, como el famoso Big Data), y especialmente cuando los resultados deben ser entregados en tiempo real.

Por otro lado, tampoco hay soporte generalizado para bases de datos NoSQL, y esto podría ser un problema a la hora de pedir ayuda. Sin embargo, si existen herramientas de software que apoyan el funcionamiento de NoSQL, tales como Hadoop, que divide el trabajo que se realiza en varios servidores en un clúster. Cabe destacar también, que con la llegada del Cloud Computing, hay más proveedores con servidores en “la nube” y una variada oferta de almacenamiento, que hace innecesario adquirir hardware con el fin de hacer un análisis basado en NoSQL.

Consideraciones de gestión a tener en cuenta

Para concluir esta guía, cualesquiera sea la base de datos que elija para su proyecto deberá tener en cuenta que tendrá que adquirir tecnología y desarrollar las habilidades de su personal de TI, es decir, capacitación y entrenamiento. Asegúrese también de que los costos encajen en el contexto de su proyecto empresarial. Recuerde que la tecnología desconocida requiere de tiempo para recibir el veto de los usuarios y también de tiempo para desarrollar las habilidades de su personal de TI. Seguramente su personal de TI sabe cómo lidiar con bases de datos convencionales, pero mucho de ese conocimiento no se transferirá directamente. Una buena idea en este punto es partir con experimentos a pequeña escala o prototipos, para ir adquiriendo experiencia.

Por otro lado, hay que tener en cuenta que los proveedores de bases de datos siempre están trabajando para hacer frente a las limitaciones propias del software y el hardware,  y agregando nuevas funcionalidades para satisfacer las nuevas necesidades de manejo de grandes volúmenes de datos, y quizás ello requiera de cambiar algunas técnicas y prácticas de sus desarrolladores para asimilar e internalizar su uso.

Finalmente, es muy probable que cometa errores. Mientras menos costosos sean, mejor. Por lo que  identificar la mejor tecnología de base de datos para sus proyectos de análisis e inteligencia de negocios, es un buen punto de partida. Y este es el espíritu de esta guía. Buena suerte!.

2014/12/08

SQL SERVER - Nombre de los meses entre intervalos de fechas

Como listar el nombre de los meses entre dos intervalos de tiempo?.
He aquí una manera de lograrlo.
 
DECLARE @StartDate DATETIME
       ,@EndDate DATETIME;
SELECT @StartDate = '20140301' -- March
      ,@EndDate = '20140901'; -- September
SELECT DATENAME(MONTH ,DATEADD(MONTH ,nos.monthnos ,@StartDate)) AS MonthName
FROM   (
           SELECT 1 monthnos UNION SELECT 2 UNION SELECT 3
           UNION SELECT 4 UNION SELECT 5 UNION SELECT 6
           UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
           UNION SELECT 10 UNION SELECT 11 UNION SELECT 12
       ) nos
WHERE  nos.monthnos<= DATEDIFF(MONTH ,@StartDate ,@EndDate);

2014/11/04

Tamaño bases de datos SQL Server

Una de las grandes preocupaciones al tener una aplicación con una o varias bases de datos es el tamaño de los archivos de logs y data, que si no se crea un plan de mantenimiento o una buena configuración acorde a las necesidades pueden llegar a crecer desproporcionadamente.

Para conocer el estado de todos los archivos de una instancia podemos consultarle a Master el tamaño de todos los archivos contenidos en la instancia.
 
SELECT NAME              AS 'Nombre Archivo'
      ,FILENAME          AS 'Dirección Fisica'
      ,CASE groupid
            WHEN 1 THEN 'File'
            ELSE 'Log'
       END               AS 'Tipo archivo'
      ,SIZE              AS Tamaño
      ,(SIZE*8)/(1024.)  AS TamañoEnMBs
FROM   MASTER..sysaltfiles
ORDER BY
       SIZE                 DESC

Si tenemos el servicio de Database Mail habilitado podríamos configurar un job semanal o mensual que esté revisando con esta sentencia y si el tamaño de algún archivo específico sobrepasa el tamaño deseado enviar un correo en forma de alerta al Administrador(es).

2014/06/12

Tablas y su numero de filas en SQL Server

El siguiente script permite ver el nombre de las tablas y su numero de filas en una base de datos.
 
SELECT sysobjects.Name  AS NombreTabla,
       sysindexes.Rows  AS TotalFilas
FROM   sysobjects
       INNER JOIN sysindexes
            ON  sysobjects.id = sysindexes.id
WHERE  TYPE = 'U'
       AND sysindexes.IndId < 2
ORDER BY
       sysobjects.Name
Una vez ejecutada la consulta.

2014/06/09

Eliminar todas las conexiones activas en una base de datos

Permite cerrar las conexiones abiertas de una base de datos en SQL Server, cuando quieres  alterar y/o eliminar una tabla o base de datos y no se puedes porque existen conexiones activas que lo impiden, solo debes de ejecutar el siguiente script.
 
CREATE PROCEDURE dbo.KillConexiones 
    @dbName SYSNAME
AS
BEGIN
    SET NOCOUNT ON
    DECLARE @spid     INT,
            @cnt      INT,
            @sql      VARCHAR(255)
    
    SELECT @spid = MIN(spid),
           @cnt     = COUNT(*)
    FROM   MASTER..sysprocesses
    WHERE  dbid     = DB_ID(@dbname)
           AND spid != @@SPID
    
    PRINT 'Eliminando ' + RTRIM(@cnt) + ' procesos.'
    WHILE @spid IS NOT NULL
    BEGIN
        PRINT 'Eliminando Proceso ' + RTRIM(@spid)
        SET @sql = 'KILL ' + RTRIM(@spid)
        EXEC (@sql)
        SELECT @spid = MIN(spid),
               @cnt     = COUNT(*)
        FROM   MASTER..sysprocesses
        WHERE  dbid     = DB_ID(@dbname)
               AND spid != @@SPID
        
        PRINT RTRIM(@cnt) + ' Procesos por eliminar.'
    END
END
GO

Encontrar los queries que consumen mas recursos

Los DMVs (Dynamic Management Views) son una magnifica forma de encontrar información de performance a partir de SQL Server 2005 en adelante (2008/2008R2/2012).

En este query de Pinal Dave se utilizan DMVs para encontrar los queries que mas consumen en un server SQL Server 2005/2008 (recordar que este script funciona solo en bases compatibles 2005/2008).
 
SELECT TOP 10 SUBSTRING(
           qt.TEXT,
           (qs.statement_start_offset / 2) + 1,
           (
               (
                   CASE qs.statement_end_offset
                        WHEN -1 THEN DATALENGTH(qt.TEXT)
                        ELSE qs.statement_end_offset
                   END - qs.statement_start_offset
               ) / 2
           ) + 1
       ),
       qs.execution_count,
       qs.total_logical_reads,
       qs.last_logical_reads,
       qs.total_logical_writes,
       qs.last_logical_writes,
       qs.total_worker_time,
       qs.last_worker_time,
       qs.total_elapsed_time / 1000000     total_elapsed_time_in_S,
       qs.last_elapsed_time / 1000000      last_elapsed_time_in_S,
       qs.last_execution_time,
       qp.query_plan
FROM   sys.dm_exec_query_stats qs
       CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
ORDER BY
       qs.total_logical_reads DESC -- logical reads
       -- ORDER BY qs.total_logical_writes DESC -- logical writes
       -- ORDER BY qs.total_worker_time DESC -- CPU time
Obviamente se puede cambiar el ordenamiento del script para destacar otro criterio de busqueda.

No está de más destacar un conjunto de queries, los DMVs AllStars, que se puede descargar aquí y que es una interesante herramienta para todo DBA en busca de detectar problemas de performance.

2014/06/02

Convertir números a letras en SQL Server

Función para poder convertir un monto numérico en un monto en letras, muy útil si se quiere hacer una descripción de un monto para alguna factura o boleta. Primero crearemos la función llamada "fn_ConvertirNumeroLetras" que recibe 2 parámetros, uno es el numero que deseamos convertir a letras y el otro el nombre de la moneda que deseamos concatenarlo al monto.
 
/*********************************************************************************
  NOMBRE:        fn_ConvertirNumeroLetra
  PROPOSITO: CONVERTIR NUMEROS A LETRAS.
  VERSIONES:
      Ver      Fecha        Autor               Descripción (inc. Req/inc)
     ------  ----------  ---------------    ------------------------------------
      1.0    01/06/2014  EDGAR CALZADA      CREACION
 *********************************************************************************/
 CREATE FUNCTION fn_ConvertirNumeroLetra
 (
        @Numero     NUMERIC(18, 2),
        @Moneda     VARCHAR(100)
 )
 RETURNS VARCHAR(512)
 AS
 BEGIN
        DECLARE @lnEntero       INT,
                @lcRetorno      VARCHAR(512),
                @lnTerna        INT,
                @lcMiles        VARCHAR(512),
                @lcCadena       VARCHAR(512),
                @lnUnidades     INT,
                @lnDecenas      INT,
                @lnCentenas     INT,
                @lnFraccion     INT,
                @resultado      AS VARCHAR(512)
       
        SELECT @lnEntero = CAST(@Numero AS INT),
               @lnFraccion     = (@Numero - @lnEntero) * 100,
               @lcRetorno      = '',
               @lnTerna        = 1
       
        WHILE @lnEntero > 0
        BEGIN
            /* WHILE */
            -- Recorro terna por terna      
            SELECT @lcCadena = ''          
            SELECT @lnUnidades = @lnEntero % 10            
            SELECT @lnEntero = CAST(@lnEntero / 10 AS INT)          
            SELECT @lnDecenas = @lnEntero % 10      
            SELECT @lnEntero = CAST(@lnEntero / 10 AS INT)          
            SELECT @lnCentenas = @lnEntero % 10            
            SELECT @lnEntero = CAST(@lnEntero / 10 AS INT)
            -- Analizo las unidades        
            SELECT @lcCadena = CASE /* UNIDADES */
                                    WHEN @lnUnidades = 1 AND @lnTerna = 1 THEN
                                         'UNO ' + @lcCadena
                                    WHEN @lnUnidades = 1 AND @lnTerna <> 1 THEN
                                         'UN ' + @lcCadena
                                    WHEN @lnUnidades = 2 THEN 'DOS ' + @lcCadena
                                    WHEN @lnUnidades = 3 THEN 'TRES ' + @lcCadena
                                    WHEN @lnUnidades = 4 THEN 'CUATRO ' + @lcCadena
                                    WHEN @lnUnidades = 5 THEN 'CINCO ' + @lcCadena
                                    WHEN @lnUnidades = 6 THEN 'SEIS ' + @lcCadena
                                    WHEN @lnUnidades = 7 THEN 'SIETE ' + @lcCadena
                                    WHEN @lnUnidades = 8 THEN 'OCHO ' + @lcCadena
                                    WHEN @lnUnidades = 9 THEN 'NUEVE ' + @lcCadena
                                    ELSE @lcCadena
                               END /* UNIDADES */
            -- Analizo las decenas
            SELECT @lcCadena = CASE /* DECENAS */
                                    WHEN @lnDecenas = 1 THEN CASE @lnUnidades
                                                                  WHEN 0 THEN
                                                                       'DIEZ '
                                                                  WHEN 1 THEN
                                                                       'ONCE '
                                                                  WHEN 2 THEN
                                                                       'DOCE '
                                                                  WHEN 3 THEN
                                                                       'TRECE '
                                                                  WHEN 4 THEN
                                                                       'CATORCE '
                                                                  WHEN 5 THEN
                                                                       'QUINCE '
                                                                  ELSE 'DIECI' + @lcCadena
                                                             END
                                    WHEN @lnDecenas = 2 AND @lnUnidades = 0 THEN
                                         'VEINTE ' + @lcCadena
                                    WHEN @lnDecenas = 2 AND @lnUnidades <> 0 THEN
                                         'VEINTI' + @lcCadena
                                    WHEN @lnDecenas = 3 AND @lnUnidades = 0 THEN
                                         'TREINTA ' + @lcCadena
                                    WHEN @lnDecenas = 3 AND @lnUnidades <> 0 THEN
                                         'TREINTA Y ' + @lcCadena
                                    WHEN @lnDecenas = 4 AND @lnUnidades = 0 THEN
                                         'CUARENTA ' + @lcCadena
                                    WHEN @lnDecenas = 4 AND @lnUnidades <> 0 THEN
                                         'CUARENTA Y ' + @lcCadena
                                    WHEN @lnDecenas = 5 AND @lnUnidades = 0 THEN
                                         'CINCUENTA ' + @lcCadena
                                    WHEN @lnDecenas = 5 AND @lnUnidades <> 0 THEN
                                         'CINCUENTA Y ' + @lcCadena
                                    WHEN @lnDecenas = 6 AND @lnUnidades = 0 THEN
                                         'SESENTA ' + @lcCadena
                                    WHEN @lnDecenas = 6 AND @lnUnidades <> 0 THEN
                                         'SESENTA Y ' + @lcCadena
                                    WHEN @lnDecenas = 7 AND @lnUnidades = 0 THEN
                                         'SETENTA ' + @lcCadena
                                    WHEN @lnDecenas = 7 AND @lnUnidades <> 0 THEN
                                         'SETENTA Y ' + @lcCadena
                                    WHEN @lnDecenas = 8 AND @lnUnidades = 0 THEN
                                         'OCHENTA ' + @lcCadena
                                    WHEN @lnDecenas = 8 AND @lnUnidades <> 0 THEN
                                         'OCHENTA Y ' + @lcCadena
                                    WHEN @lnDecenas = 9 AND @lnUnidades = 0 THEN
                                         'NOVENTA ' + @lcCadena
                                    WHEN @lnDecenas = 9 AND @lnUnidades <> 0 THEN
                                         'NOVENTA Y ' + @lcCadena
                                    ELSE @lcCadena
                               END /* DECENAS */
            -- Analizo las centenas        
            SELECT @lcCadena = CASE /* CENTENAS */
                                    WHEN @lnCentenas = 1 AND @lnUnidades = 0 AND @lnDecenas
                                         = 0 THEN 'CIEN ' +
                                         
                                         @lcCadena
                                    WHEN @lnCentenas = 1 AND NOT(@lnUnidades = 0 AND @lnDecenas = 0) THEN
                                         'CIENTO ' + @lcCadena
                                    WHEN @lnCentenas = 2 THEN 'DOSCIENTOS ' + @lcCadena
                                    WHEN @lnCentenas = 3 THEN 'TRESCIENTOS ' + @lcCadena
                                    WHEN @lnCentenas = 4 THEN 'CUATROCIENTOS ' + @lcCadena
                                    WHEN @lnCentenas = 5 THEN 'QUINIENTOS ' + @lcCadena
                                    WHEN @lnCentenas = 6 THEN 'SEISCIENTOS ' + @lcCadena
                                    WHEN @lnCentenas = 7 THEN 'SETECIENTOS ' + @lcCadena
                                    WHEN @lnCentenas = 8 THEN 'OCHOCIENTOS ' + @lcCadena
                                    WHEN @lnCentenas = 9 THEN 'NOVECIENTOS ' + @lcCadena
                                    ELSE @lcCadena
                               END /* CENTENAS */
            -- Analizo la terna
           
            SELECT @lcCadena = CASE /* TERNA */
                                    WHEN @lnTerna = 1 THEN @lcCadena
                                    WHEN @lnTerna = 2 AND (@lnUnidades + @lnDecenas + @lnCentenas <> 0) THEN
                                         @lcCadena + ' MIL '
                                    WHEN @lnTerna = 3 AND (@lnUnidades + @lnDecenas + @lnCentenas <> 0)
                                         AND
                                         
                                         @lnUnidades = 1 AND @lnDecenas = 0 AND @lnCentenas
                                         = 0 THEN @lcCadena + 'MILLON '
                                    WHEN @lnTerna = 3 AND (@lnUnidades + @lnDecenas + @lnCentenas <> 0)
                                         AND
                                         NOT (@lnUnidades = 1 AND @lnDecenas = 0 AND @lnCentenas = 0) THEN
                                         @lcCadena
                                         + ' MILLONES '
                                    WHEN @lnTerna = 4 AND (@lnUnidades + @lnDecenas + @lnCentenas <> 0) THEN
                                         @lcCadena + ' MIL MILLONES '
                                    ELSE ''
                               END /* TERNA */
            -- Armo el retorno terna a terna        
            SELECT @lcRetorno = @lcCadena + @lcRetorno      
            SELECT @lnTerna = @lnTerna + 1
        END /* WHILE */        
        IF @lnTerna = 1
            SELECT @lcRetorno = 'CERO'
       
        SELECT @resultado = RTRIM(@lcRetorno) + ' CON ' + LTRIM(STR(@lnFraccion, 2))
               + '/100 ' + @Moneda
       
        RETURN @resultado
 END
 GO
 
 -- Para ejecutarlo solo nos bastara con llamar a la función y pasarle los 2 parámetros mencionados.
 SELECT [dbo].fn_ConvertirNumeroLetra(125.50, 'Nuevos Soles')
 -- Esto nos dará como resultado lo siguiente.
 -- CIENTO VEINTICINCO CON 50/100 Nuevos Soles
 

2014/05/04

SQL SERVER - Envía las copias de seguridad a una carpeta de red, servidor FTP, Dropbox, Google Drive o Amazon S3

Déjenme decirles acerca de una de las herramientas más útiles de SQL que cada DBA debe utilizar - es SQLBackupAndFTP . He estado utilizando esta herramienta desde el año 2009 - y que es el primer programa que se instala en el servidor SQL. Descargue una versión gratuita, la configuración de 1 minuto y las copias de seguridad diarias están a salvo en la nube. 
En resumen, SQLBackupAndFTP
  • Crea la base de datos SQL Server y archivo de copias de seguridad en la fecha prevista
  • Comprime y cifra las copias de seguridad
  • Envía copias de seguridad a una carpeta de red, servidor FTP, Dropbox, Google Drive o Amazon S3
  • Envía notificaciones por correo electrónico sobre el éxito o el fracaso del trabajo
SQLBackupAndFTP viene en versiones gratis y pagados (desde $ 29) - Véase la comparación de versiones . La versión gratuita es totalmente funcional para las copias de seguridad ad hoc ilimitadas o para copias de seguridad programadas de hasta dos bases de datos - será suficiente para muchos clientes pequeños.
Lo que más me ha impresionado desde el principio - es que he entendido cómo funciona y era capaz de configurar el trabajo de una sola forma (ver Imagen 1 - forma principal arriba)
  1. Conectarse a su servidor SQL y seleccione las bases de datos para hacer copia de seguridad
  2. Haga clic en "Añadir destino de copia de seguridad" para configurar las copias de seguridad donde deben ir a (la red, servidor FTP, Dropbox, Google Drive o Amazon S3)
  3. Ingrese su correo electrónico para recibir confirmaciones por correo electrónico
  4. Establece la hora para comenzar backups completos diarios (o vaya a Configuración si necesita copias de seguridad diferenciales o del registro de transacciones en un horario flexible)
  5. Pulse el botón "Ejecutar ahora" para poner a prueba
Se puede llegar a este formulario si hace clic en los botones "Configuración" en la sección "Programación". Seleccione qué tipos de copias de seguridad y la frecuencia con que desea ejecutar de ellas y ver las copias de seguridad programadas en la lista de "plan de respaldo estimado"

El tutorial detallado está disponible en el sitio web del desarrollador.
Junto con la configuración SQLBackupAndFTP le da la opción de instalar "One-Click SQL Restore" (se puede instalar autónomo también) - una herramienta básica para la restauración de las copias de seguridad simplemente completa.
Sin embargo básico, puede arrastrar y colocar en él el archivo zip creado por SQLBackupAndFTP, se baja la cremallera del archivo BAK, si es necesario, se conecta con el servidor SQL en el inicio, selecciona la base de datos a la derecha, es lo suficientemente inteligente como para reiniciar el servidor para soltar las conexiones abiertas en caso de necesidad - muy útil para desarrolladores que necesitan para restaurar las bases de datos a menudo.
Usted puede preguntar por qué es esta herramienta es mejor que las tareas de mantenimiento disponibles en SQL Server? Mientras que las tareas de mantenimiento son fáciles de configurar, SQLBackupAndFTP es todavía muy fácil e integra soluciones para la compresión, cifrado, FTP, almacenamiento en la nube y el correo electrónico que lo hacen superior a las tareas de mantenimiento en todos los aspectos.
En una cara de la moneda SQLBackupAndFTP no es la herramienta más lujoso para gestionar copias de seguridad o consultar su salud. Sólo funciona con fiabilidad en las instancias locales de SQL Server. En otras palabras, tiene que ser instalado en el servidor de SQL en sí. Para los servidores remotos que utiliza secuencias de comandos que es menos fiable. Esta limitación es en realidad inherente a servidor SQL como mandato BACKUP DATABASE crea la copia de seguridad no en el cliente, pero en el propio servidor.
Esta herramienta es compatible con casi todas las versiones conocidas de SQL Server. Se trabaja con SQL Server 2008 (todas las versiones) y muchas de las versiones anteriores. Es especialmente útil para SQL Server Express 2005 y SQL Server Express 2008, ya que carecen de herramientas integradas para la copia de seguridad.
Recomiendo esta herramienta a todos los administradores de bases. Ellos deben absolutamente probar, ya que es gratis y hace exactamente lo que promete. Puede descargar una copia gratuita de la herramienta desde aquí.
Referencia:  Pinal Dave ( http://blog.SQLAuthority.com )