Eliminar todas las conexiones activas de una base de datos

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

Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...

Traducción del Checklist de Mejores Prácticas para ser un DBA excepcional por Brad McGehee

Mejores Prácticas para ser un DBA excepcional SQL Server (redactado por el genial Brad McGehee )

1. Ingresa a un SQL grupo de usuarios (chapters.sqlpass.org)
2. Únete a SQL PASS (www.sqlpass.org)
3. Asistir a por lo menos una conferencia de profesionales cada año.
4. Asistir a por lo menos una sesión de entrenamiento cada año.
5. Lea por lo menos cuatro libros sobre SQL Server cada año.
6. Lea el libro electrónico Cómo convertirse en un DBA excepcional (descarga free en red-gate.com)
7. Aprenda todo lo que pueda acerca de su trabajo, especialmente aquellas áreas que nadie más le gusta o quiere dominar.
8. Sea voluntario en su trabajo para tareas nuevas y difíciles que le harán conocer en toda su organización.
9. Instale SQL Server en una computadora portátil o de escritorio y practique nuevos aspectos de SQL Server, especialmente de SQL Server 2008 y 2008R2 y del nuevo denali (2010).
10. Participar en los foros de SQL Server (preguntar y responder preguntas)
1. www.SQLServerCentral.com
2. http://ask.sqlservercentral.com/com
3. www.microsoft.com / comunidades / grupos de noticias / en-us / default.aspx
11. Obtenga la certificación como DBA de SQL Server:
1. a. Microsoft Certified Technology Specialist (http://www.microsoft.com/learning/en/us/certification/cert-sql-server.aspx # Tab2)
2. b. TI de Microsoft Certified Professional (http://www.microsoft.com/learning/en/us/certification/cert-sql-server.aspx # tab3)















Día a día

1. Compruebe los registros de eventos del S.O. y los registros de SQL Server para detectar eventos inusuales.
2. Verifique que todos los trabajos programados se han ejecutado correctamente.
3. Confirme que las copias de seguridad se han hecho y guardado con éxito a un lugar seguro.
4. Monitoree el espacio en disco para asegurarse de que sus servidores de SQL no se quedarán sin espacio en disco. Para un mejor rendimiento, todos los discos deben tener 15% o más de espacio libre.
5. A lo largo del día, haga un seguimiento periódico de rendimiento utilizando Monitor de sistema y de perfiles / Traza de SQL.
6. Monitorear regularmente e identificar problemas de bloqueo.
7. Mantenga un registro de los cambios que realice a los servidores, incluyendo la documentación de los problemas de rendimiento a identificar y corregir.
8. Crear alertas de SQL Server para que le avise de posibles problemas, y las envíe por mail. Tomar las medidas necesarias.
9. Regularmente restaure copias de seguridad en un servidor de prueba para verificar que realmente los puede restaurar. No es necesario para restaurar todas las copias de seguridad todos los días, pero debiera hacerlo a menudo para asegurarse de que usted tiene buenas copias de seguridad.
10. Tómese su tiempo para aprender algo nuevo como un DBA para promover su desarrollo profesional.

Instalación

1. Siempre documente las instalaciones de modo completo, aun cuando parezca redundante, esto hará que las instancias de SQL Server se pueden reproducir fácilmente en caso de emergencia.
2. Si es posible, instalar y configurar todas las instancias de SQL Server de una manera consistente, de la misma forma , basándose en las normas pre-acordadas de su organización.
3. No instale los servicios de SQL Server que no se utilizan, como Microsoft indexación de texto completo, Reporting Services o Analysis Services.
4. Para obtener el mejor rendimiento de SQL Server, detenga todos los servicios del sistema operativo que no son necesarios.
5. Para un óptimo rendimiento de SQL Server, no ejecutar al SQL Server junto con ninguna otra aplicación.
6. Para obtener el mejor rendimiento I / O, busque los archivos de base de datos (. mdf) y archivos de registro (. ldf) en discos separados para aislar a los patrones de acceso a disco.
7. Si tempdb se utiliza en gran medida, pongalo en un disco aparte.
8. No instale SQL Server en un controlador de dominio.
9. Asegúrese de que SQL Server se instala en una partición NTFS.
10. No utilice NTFS con cifrado de archivos de datos (EFS) y ni compresión de datos sobre el disco de la base de datos de SQL Server y los archivos de registro.

Actualizar1. Ejecute el Upgrade Advisor de SQL Server antes de actualizar. Haga los cambios necesarios antes de realizar la actualización.2. Realizar una actualización de prueba antes de actualizar los servidores de producción. Y no se olvide de probar las aplicaciones con la nueva versión también.3. Antes de actualizar, asegúrese de tener un plan para revertir los cambios en caso que la actualización sea problemática.4. No actualizar clústeres de SQL Server en su lugar. En cambio, a reconstruirlos en un nuevo hardware.5. Si actualiza desde una versión anterior de SQL Server, debe actualizar todas las estadísticas en todas las bases de datos. Esto se debe a que las estadísticas no se actualizan automáticamente durante el proceso de actualización.

Seguridad

  1. Asegure la seguridad física de cada Servidor SQL , previniendo que cualquier usuario no autorizado pueda acceder físicamente a sus servidores.
  2. Instalar solamente las mínimas y necesarias nettwork libraries y network protocols en sus instancias SQL
  3. Minimize el número de usuarios sysadmins con acceso a SQL Server.
  4. Como DBA, logueesé como sysadmin solo cuando realmente lo necesite. Cree cuentas específicas para DBAs para que puedan acceder a SQL Server cuando no necesiten privilegios sysadmin.
  5. Asigne a la cuenta "sa" una password realmente compleja y no la use nunca para loguearse a SQL Server. En vez de eso use una cuenta Windows Authentication para acceder SQL Server como sysadmin.
  6. Dele a los usuarios los mínimos permisos necesarios que le permitan a ellos realizar su trabajo.
  7. De ser posible, use stored procedures o views para el acceso a los datos en vez de dejarlos acceder directamente a las tablas.
  8. De ser posible, use Windows Authentication logins en vez de SQL Server logins.
  9. Use strong passwords (combinación de mayúsculas, minúsculas, numeros y caracteres especiales) para todos los SQL Server login.
  10. No le asigne permisos al rol de base de datos "public"
  11. Remueve Logins IDs que ya no necesitan acceder a SQL Server apenas los detecte.
  12. Deshabilite el usuario "guest" en cada base de datos usando REVOKE CONNECT FROM GUEST.
  13. No use "cross database ownership chaining" si no es realmente necesario.
  14. Nunca habilite permisos a xp_cmdshell a los usuarios que no son sysadmin.
  15. Eliminar las bases de ejemplo (adventureworks, pubs, northwind) de todas las instancias de producción.
  16. Usar Windows Global Groups, o SQL Server Roles para manejar grupos de usuarios con similares permisos.
  17. No debería crear ni permitir crear network shares en servidores SQL Server.
  18. Configurar login auditing , de esta manera se puede ver quienes intentaron loguearse y los intentos fallidos de login.
  19. No use jamás la cuenta sa ni login ids que sean sysadmin como cuentas de acceso desde aplicaciones.
  20. Asegurese que sus servidores están detrás de un firewall y no están expuestos directamente a internet.
  21. En SQL Server 2005 y previos, remover el grupo de BUILTIN/Administrators para evitar que los administradores locales del servidor puedan acceder a SQL Server. En SQL Server 2008, el grupo BUILTIN/Administrators group no existe en forma predeterminada.
  22. Ejecute cada servicio SQL Server bajo una cuenta de dominio diferente.
  23. Dele a las cuentas asignadas a los servicios SQL Server los minimos permisos que le permitan al mismo ejecutarse de la manera correcta. En la mayoría de los casos los permisos de un administrador local no son necesarios y menos aún los permisos de un administrador de dominio.
  24. Cuando use queries distribuidas use linked servers en vez de remote servers. Remote servers están solo por backward compatibility.
  25. No navegue internet desde una instancia de producción de SQL Server.
  26. En vez de instalar antivirus/antispyware en un SQL Server, realice scaneos desde un servidor remoto y solo cuando la actividad del servidor SQL no sea tan alta.
  27. Agregue los service packs, tanto de SQL Server com de sistema operativo apenás estén disponibles.
  28. Considere la posibilidad de encriptar los backups con herramientas como Red Gate SQL Backup Pro u otras.
  29. Solo habilite las trazas de "C2 auditing" o "Common Criteria compliance" cuando sea realmente necesario, porque sobrecargan el servidor si están habilitadas.
  30. Considere seriamente ejecutar un SQL Server security scanner para detectar si hay huecos de seguridad en sus servidores, tanto a nivel sistema operativo como servidor de base de datos. http://searchsqlserver.techtarget.com/feature/SQL-Server-security-test-checklist
  31. Considere habilitar SSL or IPSEC para las conexiones entre sql server y los clientes.
  32. Si está utilizando SQL Server 2005/2008, habilite password policy checking.
  33. Si está usando SQL Server 2008 en un entorno de alta seguridad, considere implementar TDE, Transparent Data Encryption para proteger los datos de su servidor.
  34. Si utiliza SQL Server 2005, no use SQL Server Surface Area Configuration para desbloquear características que nunca se utilizan y que pueden traer solamente problemas de seguridad.
  35. Si está usando SQL Server 2005/2008 y crea endpoints, solo habilite permisos grant CONNECT a los logins que realmente necesitan acceder esos endpoints. Explicitamente deniegue (deny) CONNECT permissions a los endpoints que no son necesarios para los usuarios.

Mantenimiento de Jobs

  1. Evite ejecutar jobs en el mismo horario. Preferentemente cada job debe ejecutarse en su propio horario.
  2. Cuando cree jobs asegurese de incluir intercepción de errores, de loguear la actividad del job y de establecer alertas (mails por ejemplo) para asegurarse de saber al momento de cualquier fallo que pudiera ocurrir.
  3. Cree un login específico con el solo propósito de ejecutar jobs y asignele a dicho login todos los jobs.
  4. Si su job incluye código Transact-SQL, asegurese que está optimizado para que se ejecute correctamente.
  5. Periodicamente (diario, semanal, mensual) reconstruya o reorganice los índices de sus bases de datos para remover la fragmentación logica y aprovechar mejor el especio en disco.
  6. Periódicamente y como parte de sus tareas de mantenimiento, ejecute DBCC CHECKDB en todas sus bases de datos para comprobar su integridad y detectar eventuales problemas.
  7. Evite ejecutar comandos DBCC en los horarios donde se da la mayor carga de trabajo en sus servidores. Estos comandos son altamente requirientes en términos de recursos y afectan la performance.
  8. Si usted reinicia muy raramente el servicio SQL Server service, se va a encontrar con que el log de SQL Server se pone muy grande y toma mucho tiempo para cargar y ser mostrado. Usted puede cerrar el log error actual y crear uno nuevo ejecutando sp_cycle_errorlog o DBCC ERRORLOG. Establezca esto como un job semanal.
  9. Haga un script de todos los jobs y guarde esos scripts en un lugar seguro por si necesita en algun momento reconstruir los servers.

Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...

Como obtener el último registro de una categoría dada usando la función RANK

Supongamos que queremos obtener el último producto vendido de cada categoría, la forma mas sencilla de realizar esto es utilizando la función RANK particionando por la categoría y ordenando por orden inverso por la fecha de venta, luego filtramos por el rango obtenido ( rank = 1) y ahi obtenemos el último de cada categoría.

SELECT *
FROM
(
SELECT top 100 categoria_id
, producto_id
, fechadeventa, Rank() over (Partition BY categoria_id ORDER BY fechadeventa DESC ) AS rango
FROM
productosvendidos
) rs WHERE rango = 1

Hugo Bernachea
Twitter: @bernachea
el.kyrios@yahoo.com
Read More...

Cannot open user default database. Login failed. SQL 2005

En linea de comandos ejecutar la utilidad sqlcmd: sqlcmd -E -d master

Una vez dentro de la línea de comandos de SQL Server ejecutar (reemplazar miLogin con el login que no está pudiendo acceder al servidor)

alter login miLogin with default_database = master

go

Y ya estaría habilitado el acceso a la base.

Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...

Error 945 Database cannot be opened due to inaccessible files

SQL SERVER – FIX : Error 945 Database cannot be opened due to inaccessible files or insufficient memory or disk space. See the SQL Server error log for details
Este es un error mas o menos común y los pasos de verificación son los siguientes:
Paso 1: Identificar el status de la base de datos
use master
select databaseproperty(‘db_name’,'isShutdown’)

La mayor parte de las veces debería devolver 1 en esta situación.
Paso 2: Limpiar el estado interno de la Base de datos.
use master
alter database db_name set offline

Finaliza sin error en la mayoría de los casos...
Paso 3: Poner la base de nuevo Online

use master

alter database db_name set online
SQL Server verificará el log y la base de datos y si todo está ok ya tendriamos la base nuevamente online y funcional.


Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...

SQL Server 2008 Clustering en Windows Server 2008


SQL Server 2008 Clustering - Part 7 from Ramu Poonjolai on Vimeo.

Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...

xType en syscolumns

A diferencia de 'xType" en sysobjects, no es tan facil de encontrar que significan esos valores en la tabla syscolumns, teniendo en cuenta que en los Books online mencionan al xtype como "for internal purpose" (para uso interno).

La tabla que tiene esta info es sysTypes y podemos escribir un query tipo:

SELECT xtype, name [tipo] FROM systypes ORDER BY xType

y esto devuelve

XType tipo
----------------
34 image
35 text
36 uniqueidentifier
48 tinyint
52 smallint
56 int
58 smalldatetime
59 real
60 money
61 datetime
62 float
98 sql_variant
99 ntext
104 bit
106 decimal
108 numeric
122 smallmoney
127 bigint
165 varbinary
167 varchar
173 binary
175 char
189 timestamp
231 nvarchar
231 sysname
239 nchar
241 xml


Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...

Abraham Silberschatz - Fundamentos de Bases de Datos

UNED Fundamentos de bases de datos



Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...

SQL Injection Attacks

Un pequeño instructivo con algunas técnicas básicas de injection sql, interesante para empezar a entender estas técnicas de ataque a servidores de bases de datos:
El libro se encuentra en:

http://www.securitydocs.com/pdf/3348.PDF

Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...

Portqry - Monitor de estados de puertos TCP/IP

Portqry.exe es un utilitario que informa sobre el estado de un puerto TCP/IP.

Este utilitario se puede descargar desde:

Para línea de comandos:
http://www.microsoft.com/downloads
/details.aspx?FamilyID=89811747-C74B-4638-A2D5-AC828BDC6983&displaylang=en













Interfaz Gráfica:
http://download.microsoft.com/download/3/f/4/3f4c6a54-65f0-4164-bdec-a3411ba24d3a/portqryui.exe


















Este utilitario informa el estado de puertos de tres formas distintas:

  • Listening
    Hay un proceso a la escucha en el puerto del equipo seleccionado. Portqry.exe recibió una respuesta desde el puerto.

  • Not Listening
    No hay ningún proceso a la escucha en el puerto de destino del sistema de destino. Portqry.exe recibió el mensaje "Destino inalcanzable: Puerto inaccesible" de Protocolo de mensajes de control de Internet (ICMP) para el puerto UDP de destino. O bien, si el puerto de destino es un puerto TCP, Portqry recibió un paquete de confirmación TCP con el indicador Reset.

  • Filtered
    El puerto del equipo que seleccionó tiene activado un filtro. Portqry.exe no recibió una respuesta desde el puerto. Es posible que haya un proceso a la escucha en el puerto. De manera predeterminada, los puertos TCP se consultan tres veces y los puertos UDP una antes de que el informe indique que el puerto tiene activado un filtro.
Portqry.exe puede consultar un solo puerto, una lista ordenada de puertos o un intervalo secuencial de puertos.

Ejemplos
El comando siguiente intenta resolver "reskit.com" como una dirección IP y, a continuación, consulta el puerto TCP 25 en el host correspondiente:

portqry -n www.mundoeva.com -p tcp -e 25
El comando siguiente intenta resolver "169.254.0.11" como un nombre de host y después consulta los puertos TCP 143, 110 y 25 (en ese orden) en el host que seleccionó. Este comando también crea un archivo de registro (Portqry.log) que contiene un registro del comando que ejecutó y su resultado.

portqry -n 169.254.0.11 -p tcp -o 143,110,25 -l portqry.log

El comando siguiente intenta resolver miServidor como una dirección IP y después consulta el intervalo especificado de puertos UDP (135-139) en orden secuencial en el host correspondiente. Este comando también crea un archivo de registro (miServidor.txt) que contiene un registro del comando que ejecutó y su resultado.


portqry -n miServidor -p udp -r 135:139 -l miServidor.txt

Este utilitario es una herramienta de utilidad y que debemos tener siempre en cuenta al momento de monitorear estados de puertos remotos.


Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...

FAIL_VIRTUAL_RESERVE - Insuficiente memoria para ejecutar el query.

Este es un problema relativo al Virtual Address Space (VAS).

Este mensaje FAIL_VIRTUAL_RESERVE 589824 significa (al menos lo que yo se) que estamos fallando en asignar espacio contiguo de alocacion de 589824 bytes aprox.

Generalmente la solución es agregar el switch o parametro de startup -g 512 y reiniciar el servicio, tal como indica microsoft: http://msdn.microsoft.com/en-us/library/ms190737.aspx

If este seteo no funcionara existen algunos otros puntos a mirar:

1. Estrategia de indices para mejorar la performance de los queries y disminuir los bloqueos.
2. Minimum y Max memory size. Dejarle algo de memoria libre para el sistema operativo, al menos medio gb.
3. Aplicar los ultimos service pack y patchs, para lo cual pueden comparar su versión y patchs aplicados con respecto a la ultima en http://www.sqlteam.com/article/sql-server-versions
4. Permisos de Lock Pages in Memory Permissions para el user que ejecuta el servicio sql server
http://www.tipandtrick.net/2008/enable-lock-pages-in-memory-to-prevent-database-paging-to-disk/
5. Chequear si las estadisticas están des-actualizadas.

Una muy buena explicacion de estos temas: http://blogs.msdn.com/b/sqlserverfaq/archive/2010/02/16/how-to-find-who-is-using-eating-up-the-virtual-address-space-on-your-sql-server.aspx

Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...

The Power of Cross Join

http://weblogs.sqlteam.com/jeffs/archive/2005/09/12/7755.aspx

Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...

Cual es la diferencia entre CROSS APPLY y CROSS JOIN

Traducido de:
http://weblogs.sqlteam.com/jeffs/archive/2007/10/18/sql-server-cross-apply.aspx
Pienso que la manera mas fácil de pensar la sentencia CROSS APPLY es que es semejante a hacer un CROSS JOIN con un sub-select correlativo en vez de una tabla derivada.

Digamos, una tabla derivada es "auto-contenida" de modo que las tablas y columnas que referencia no son accesibles por el select principal, aunque variables y parámetros pueden ser referenciados.
Por ejemplo, veamos:

select A.*, b.X
from A
cross join (select B.X from B where B.Val=A.Val) b

Esta sentencia no es válida, porque A.Val está fuera del alcance al estar dentro de la tabla derivada. Esto es porque la tabla derivada es evaluada de manera independiente de las otras tablas en el Select.
Para limitar los registros en Tabla B de manera de cumplir la condición B.Val = A.Val, nosotros tenemos que hacerlo "fuera" de la tabla derivada por medio de un join o en el criterio.

select A.*, b.X
from A
cross join (select * from B) b
where A.Val = b.Val

(por supuesto, lo de arriba es equivalente a hacer un inner join en la tabla derivada o simplemente uniendo a la tabla B).

También, tengamos en cuenta que el alcance de las tablas derivadas no rige solamente para los CROSS JOINS sino que también se aplica a todos los otros JOINS (CROSS, INNER, OUTER) e incluso para UNION. Todas estas sentencias usan tablas derivadas "auto-contenidas".

Esto es diferente a un sub-select correlativo en donde el SELECT principal está en el alcance para el sub-query. El sub-select es evaluado por cada registro en el query, de manera que otras tablas y columnas en el SELECT están disponibles.

select A.*, (select B.X from B where B.Val=A.Val) as X
from A

(obviamente el subquery tiene que regresar solo un registro).

Esta es una manera facil de pensar las diferencia entre CROSS JOIN y CROSS APPLY. CROSS JOIN, tal como vimos, une a una tabla derivada, sin embargo, CROSS APPLY, a pesar de lucir como un JOIN en realidad es aplicado al subselect correlativo. Esto impone las ventajas de subselects correlativos y además tiene implicaciones a nivel de performance.

Ahora si, podemos reescribir nuestro primer ejemplo usando CROSS APPLY y quedaría de la siguiente forma:

select A.*, b.X
from A
cross apply (select B.X from B where B.Val=A.Val) b

Como ahora aplicamos un APPLY y no un JOIN, A.Val está en alcance y esto funciona ok.

Table Valued User Defined Functions

Las mismas reglas aplican cuando usamos Table-Valued User-Defined Functions:

select A.*, B.X
from A
cross join dbo.UDF(A.Val) B

Esto es no válido nuevamente. A.Val no está en alcance para ser usado por la UDF.

Lo mejor que podíamos hacer antes de SQL 2005 era usar un subselect correlativo:

select A.*, (select X from dbo.UDF(A.Val)) X
from A

Sin embargo esto no es funcionalmente equivalente. La UDF no regresa mas de un registro o eso sería un error.

Con SQL 2005 podemos también en este caso usar CROSS APPLY y todo funcionará perfectamente:

select A.*, b.X
from A
cross apply dbo.UDF(A.Val) b

Esta es una manera de pensar las diferencias entre JOIN y APPLY, JOIN combina dos resultsets separados, pero APPLY es mas que un loop que evalua un resultset una y otra vez por cada registro.
Esto significa que en general APPLY será menos eficiente que un JOIN, del mismo modo que sub-selects correlativos son menos eficientes que tablas derivadas.

Entonces, cual es la ventaja de usar CROSS APPLY en vez de un sub-select correlacionado?
Bueno, muchas ventajas, por empezar...es mucho mas poderoso !.


CROSS APPLY puede regresar múltiples registros.

Esto nos permite hacer cosas como "joinear" una tabla a una función que parsear una columna csv en esa misma tabla en multiples registros.

select A.ID, b.Val
from A
cross apply dbo.ParseCSV(A.CSV) b

Cuando la funcion ParseCSV regresa multiples registros, simplemente actua como si hubiesemos joineado una tabla, duplicando los registros en tabla A por cada registro en la tabla de join.
Esto no se puede hacer con un sub-select correlativo, porque tira error.


CROSS APPLY puede retornar múltiples columnas.

De nuevo, en un sub-select correlativo podemos devolver un solo valor.
Si escribimos un script que regrese una sumatoria, podemos usar un subselect como el siguiente:

select o.*,
(select sum(Amount) from Order o
where p.OrderDate <= o.OrderDate) as RunningSum
from Order o

Sin embargo, que pasa si queremos regresar sumas adicionales de pedidos basados en algún otro criterio (pedidos con el mismo "ordercode")?.
Necesitaríamos otro subselect correlacionado, reduciendo la eficacia de nuestro select.

select o.*,
(select sum(Amount) from Order o
where p.OrderDate <= o.OrderDate) as RunningSum,
(select sum(Amount) from Order o
where p.OrderCode = o.OrderCode and p.OrderDate <= o.OrderDate) as SameCode
from Order o

Pero con un CROSS-APPLY seria mucho mas sencillo.

select o.*, rs.RunningSum, rs.SameCode
from Order o
cross apply
(
select
sum(Amount) as RunningSum,
sum(case when p.OrderCode = o.OrderCode then Amount else 0 end) as SameCode
from Order P
where P.OrderDate <= O.OrderDate
) rs


Entonces, tenemos el beneficio de regresar multiples columnas como si fuese una tabla derivada, y también tenemos la habilidad de referenciar valores en nuestro select.
Bastante poderoso.

Con CROSS APPLY podemos facilmente recuperar columnas del registro anterior en una tabla.

select o.*, prev.*
from Order o
cross apply
(
select top 1 *
from Order P where P.OrderDate < O.OrderDate
order by OrderDate DESC
) prev

Note que el script anterior no regresará pedidos que no tengan un pedido anterior, debemos usar OUTER APPLY para asegurarnos que todos los pedidos serán regresados, incluso si no existen pedidos previos.

select o.*, prev.*
from Order o
outer apply
(
select top 1 *
from Order P where P.OrderDate < O.OrderDate
order by OrderDate DESC
) prev


Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...

Como encontrar un texto dentro de todos los stored procedures en SQL Server 2005

SELECT ROUTINE_NAME, ROUTINE_DEFINITION
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION LIKE '%foobar%'
AND ROUTINE_TYPE='PROCEDURE'

Nos valemos de la función ROUTINE_DEFINITION que nos devuelve la definición o codificación de cualquier objeto dentro una base de datos.


Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...

CXPACKET wait type en SQL Server

Problema
Tenemos un servidor con mas de un CPU y experimentamos altos valores de CXPACKET wait types. Esto ocurre por las queries que se ejecutan en paralelo y el desafío es entender como las diferentes versiones de un query pueden impactar en los valores de los CXPACKET waits. En la nota del link se analizan como cambios en un query pueden impactar en CXPACKET waits.
Solución
El objetivo del tip de la nota enlazada es incrementar la performance del query, disminuir el valor de CXPACKET waits sin reducir MAXDOP.
Veamos la nota original y los ejemplos de como recudir CXPACKET waits.

Link: http://www.mssqltips.com/tip.asp?tip=2027



Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...

Artículos de Kimball - Datawarehouse

Un seria ultra-interesante de artículos de Kimball, el gurú del Datawarehouse:
http://www.rkimball.com/html/articles.html
http://www.decisionone.co.uk/resources/KimballArticles.htm

Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...

sp_who2 - Quien, cuando, como?

En este link podemos ver una profunda explicación sobre la historia del sp_who2, desde su origen como sp no documentado hasta el dia de hoy.
En esta profunda nota se pueden ver una clara explicación y un interesante script que se puede agregar a nuestro arsenal de tools administrativas.

http://www.sqlservercentral.com/articles/sp_who2/70222/


Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...

Información acerca de los reportes scheduleados

Muchas veces tenemos una gran cantidad de reportes programados similares, pero necesitamos obtener info detallada de los mismos.

El siguiente script--->
http://www.sqlexperto.com.ar/index.php?topic=21.0 nos da la forma de obtener la lista de los reportes programados y sus jobs.



Hugo Román Bernachea
Mail de contacto: SQLServer777@gmail.com

Microsoft Certified DBA
Microsoft Certified Trainer
Twitter: @bernachea

Read More...