Generar datos de prueba para SQL Server

By Juan Carlos Heredia Mayer 25/03/2015 Base de Datos

SQL SERVERMuchas veces cuando empezamos a desarrollar un nuevo proyecto o hacemos un determinado mantenimiento a una aplicación de base de datos, necesitamos precisamente eso: datos de prueba para empezar a trabajar. Lo más simple es agregar algunos registros a nuestras tablas y probar, pero seguro que en breve no serán  suficientes y necesitaremos más datos, ya sea para pruebas de velocidad y rendimiento, filtros, paginación, etc.

Existen herramientas de terceros que permiten generar datos aleatorios, pero son productos caros y no siempre es factible adquirirlos. Entonces, ¿cómo podemos generar esos datos de prueba en nuestras propias bases de datos?.

Solución

Os mostraré algunos trucos para generar datos aleatorios a partir de unos cuantos registros y multiplicarlos por miles. Cada tipo de datos necesita un enfoque diferente como se puede ver a continuación.

Datos Numéricos

En primer lugar, sin duda necesitaremos generar algunos datos numéricos. Lo primero que se nos ocurriría a priori es usar la función RAND(). Desafortunadamente esta función se invoca una sola vez por consulta, no una vez por cada fila, por lo tanto, devuelve el mismo valor para cada registro afectado por la consulta. Así que sugiero el uso de otros métodos, a menos que se desea utilizar un valor de inicialización distinto para cada llamada, que puede ser muy trabajoso para la generación de un volumen masivo de datos.

Lo mejor para obtener un valor aleatorio real, es usar la función NEWID () junto con la función CHECKSUM(). La siguiente expresión devuelve un valor entero aleatorio:

SELECT CHECKSUM(NEWID())

Esto devuelve un número entero positivo o negativo, pero podemos hacer una modificación para que devuelva valores positivos y decimales, si es lo que necesitamos.

SELECT ABS(CHECKSUM(NEWID()))/100.0

Por supuesto esta expresión es aplicable para agregar o modificar un registro. Por ejemplo la siguiente sentencia agregaría un nuevo registro y se puede ejecutar cuantas veces sea necesario para generar muchos registros:

INSERT INTO [dbo].[TablaPrueba]
           ([ENTERO],
            [DECIMAL])
     VALUES
           (ABS(CHECKSUM(NEWID())),
            ABS(CHECKSUM(NEWID()))/100.0)

Después de ejecutar la sentencia varias veces podemos consultar los datos:

SELECT [ENTERO], [DECIMAL]
    FROM [dbo].[TablaPrueba]
SQL SELECT

La siguiente instrucción actualiza registros existentes en lote, cada registro tendría valores distintos:

UPDATE [dbo].[TablaPrueba]
   SET [DECIMAL] = ABS(CHECKSUM(NEWID()))/100.0

Datos de Texto

Es posible usar la misma función NEWID(), para generar textos. La siguiente sentencia devolverá un valor aleatorio algo así como: 4F9008A9-BA3D-4077-A17E-724E2AF962AD.

SELECT CONVERT(VARCHAR(MAX),NEWID())


Sin embargo como se puede ver generará textos basados en letras y números que no tendrán un significado especial. Los datos de texto requieren especial atención,  si se desea tener una base de datos con un cierto contenido razonable. Lo primero que se debería hacer es construir un diccionario inicial y luego utilizarlo para generar más filas. Por ejemplo, es común el uso de nombres en varios campos de la base de datos. El siguiente ejemplo muestra cómo crear una tabla que contendrá 100 nombres diferentes en pocos segundos.

-- Crear Tabla para Nombres 
CREATE TABLE [NOMBRES] (NOMBRE [varchar](20))  
-- Crear Tabla para Apellidos 
CREATE TABLE [APELLIDOS] (APELLIDO [varchar](20))  
-- Llenar algunos nombres
INSERT INTO NOMBRES VALUES ('Juan')  
INSERT INTO NOMBRES VALUES ('Carlos')  
INSERT INTO NOMBRES VALUES ('Pablo')  
INSERT INTO NOMBRES VALUES ('María')  
INSERT INTO NOMBRES VALUES ('Enrique')  
INSERT INTO NOMBRES VALUES ('Jorge')  
INSERT INTO NOMBRES VALUES ('Luis')  
INSERT INTO NOMBRES VALUES ('Raúl')  
INSERT INTO NOMBRES VALUES ('Sofia')  
INSERT INTO NOMBRES VALUES ('Jesús')  
-- Llenar algunos apellidos  
INSERT INTO APELLIDOS VALUES ('Arias')  
INSERT INTO APELLIDOS VALUES ('Pérez')  
INSERT INTO APELLIDOS VALUES ('Pinto')  
INSERT INTO APELLIDOS VALUES ('Sánchez')  
INSERT INTO APELLIDOS VALUES ('Herrera')  
INSERT INTO APELLIDOS VALUES ('Rojas')  
INSERT INTO APELLIDOS VALUES ('Poma')  
INSERT INTO APELLIDOS VALUES ('Redondo')  
INSERT INTO APELLIDOS VALUES ('Tapia')  
INSERT INTO APELLIDOS VALUES ('Gil')  
-- Generar 10x10=100 nombres diferentes  
SELECT * INTO TESTTABLE FROM NOMBRES CROSS JOIN APELLIDOS

Con los ejemplos anteriores se pueden generar rápidamente más y más registros diferentes para unas cuantas tablas de una base de datos, para así tener datos de prueba al momento de implementar una aplicación. El uso de  los CROSS JOIN Y SELF JOIN pueden crear fácilmente gran cantidad de datos así que se debería tener cuidado al utilizar tablas muy grandes o con muchos datos.

Si quieres más trucos de este tipo te invito a echarle un vistazo a este Nuevo libro de SQL Server 2014 en Español

Comprar en AmazonSQL Server 2014 | Amazon Kindle Comprar en Google PlaySQL Server 2014 | Google Play Books

Seleccionar Registros aleatorios en SQL Server

By Juan Carlos Heredia Mayer 24/03/2015 Base de Datos

SQL Server

Hace ya bastante tiempo atrás tenía la necesidad de obtener un número de registros aleatorios de una tabla en SQL Server. Específicamente lo necesitaba para un sistema de evaluación automática en la que se tenía un banco de preguntas en una tabla de la cuale al abrir el programa se tenía que mostrar 20 preguntas al azar. La solución que encontré fue usar la función NEWID() de SQL Server. Y ahora que he recibido una pregunta al respecto he decidido compartir la respuesta aquí.

NEWID() Crea un valor único del tipo uniqueidentifier, por lo tanto al generar un valor único por registro podemos ordenar y filtrar N registros por ese campo. Si la tabla se llama PREGUNTAS la siguiente sentencia nos devolvería 20 registros diferentes cada vez:

SELECT TOP 20 * FROM preguntas ORDER BY NEWID()

Espero que os sea de utilidad.

Si quieres más trucos de este tipo te invito a echarle un vistazo a este Nuevo libro de SQL Server 2014 en Español

Comprar en AmazonSQL Server 2014 | Amazon Kindle Comprar en Google PlaySQL Server 2014 | Google Play Books

Conexión Remota con PowerShell 2.0

By Juan Carlos Heredia Mayer 28/02/2015 Networking

La capacidad de crear una conexión remota es una de las principales diferencias más y quizás la más importante entre PowerShell 1.0 y 2.0. Sin embargo, la creación de una sesión remota(para interactuar)  por primera vez, es una de las tareas un tanto complicadas en PowerShell, especialmente en entornos donde no existe un controlador de domino (Directorio Activo). Pero como para todo hay solución he aquí como hacerlo, de forma muy sencilla y útil.

El objetivo principal sería es elevar los permisos de confianza para permitir conexiones de cualquier equipo. Primero verificamos la existencia del espacio de nombres WSMan (Control de Credenciales) el cual está direccionado al servicio WinRm.

Get-PsProvider

Luego verificamos su configuración (específicamente TrustedHosts)

cd wsman:
cd localhost\client
dir

Ahora la parte más importante. Permitir conexiones de cualquier equipo

# Permitir conexiones de cualquier equipo
Set-Item WSMan:\localhost\Client\TrustedHosts *
# Reiniciar el servicio
restart-Service winrm

Importante: Este método funciona en un entorno con equipos no pertenecientes a un dominio. Si hay un Directorio activo se puede configurar TrustedHosts via las políticas de grupo (Group Policy)

Hecha la primera parte, continuamos con la configuración del servicio WinRM y dar permisos a los equipos que se han de conectar TrustedHosts.

Los pasos a seguir serían:

En el servidor desde el que nos queremos conectar

Get-Service winrm
Enable-PSRemoting –force
winrm s winrm/config/client ‘@{TrustedHosts=”*”}’
winrm quickconfig

Conexión entre máquinas (desde la estación de trabajo)

New-PSSession -computername Servidor -Credential Usuario
Get-PSSession
Enter-PSSession -ID Identificador_obtenido_con_el_Get-Pssession

NOTA:

PowerShellTrustedHosts=”*” es una política que permite que servidores serán los que se puedan conectar remotamente, en ejemplo, se pone un asterisco que equivale a se aceptan conexiones desde cualquier máquina. Si lo que se necesita es filtrar las conexiones se debe personalizar este parámetro del servicio WINRM ( winrm /? ).

En un entorno de trabajo con máquinas virtuales, me encontré con otra dificulta y es que no se podían habilitar las conexiones remotas (Enable-PSRemoting –force). Encontré un artículo en la red que habla como solucionar el problema: Enabling Remoting on Windows 7 with PowerShell 2.0

Espero que os sirva de ayuda.