You are on page 1of 11

thesolidqjournal

database administration

48

Por Herbert Albert


y Gianluca Hotz

Disfrutando con PowerShell

Automatizacin del proceso de


migracin de bases de datos
En el nmero de este mes, vamos a construir una solucin sencilla para automatizar la
migracin de bases de datos entre versiones distintas de SQL Server utilizando una mezcla
de PowerShell y scripts de T-SQL.
a migracin de bases de datos de SQL Server
es un tema muy amplio que generalmente
implica muchas puntos y escenarios crticos a planificar cuidadosamente. Slo para dar una idea, el
texto oficial Technical Reference Guide de SQL
Server 2008 R2 actualizar es de casi 500 pginas.
Preparar y probar un procedimiento de migracin slido es importante, y las secuencias de
comandos pueden ser muy tiles para automatizar
parte del proceso. En algunos casos, por ejemplo
cuando desea reducir al mnimo el tiempo de inactividad, es realmente la nica forma prctica para preparar, probar y ejecutar una migracin.
La previsibilidad es slo una de las ventajas,
pero poder automatizar el proceso puede ser til
tambin en otras situaciones, como cuando tienes
docenas o incluso cientos de bases de datos que
deben migrarse y tendremos que actualizar peridicamente una copia en un entorno de prueba.

Escenario de migracin simplificada


Para facilitar las cosas, supongamos un escenario
de migracin simplificada donde las actividades se
dividen en los siguientes grupos principales:
1. Inventario de bases de datos que se deben
migrar.
2. Anlisis Esttico del cdigo de la base de
datos y de la carga de trabajo de seguimiento
(en este caso, puede ser de tipo asistido con
el Asesor de Actualizaciones de SQL Server).
3. Desarrollo de procedimientos de migracin.

4. Ejecucin de pruebas de procedimientos de


migracin.
5. La ejecucin de los test para la aplicacin.
En primer lugar, cuando estemos haciendo el inventario puede ocurrir que algunas bases de datos tengan
que pasar por procesos o prcticas de sobra conocidas.
Por ejemplo, esto sucede a menudo con bases de
datos utilizadas para: la centralizacin de soluciones de
Backup, de soluciones antivirus, soluciones ERP, soluciones CMS, etctera, etctera. Estas bases de datos
son generalmente malas candidatos para una solucin
de migracin generalizada porque tal vez tengan que
seguir un conjunto de acciones muy diferente.
En algunos casos es posible que se puedan
migrar varias bases de datos utilizando un procedimiento comn o al menos un conjunto de acciones
comunes antes a aplicar ms otro conjunto de
acciones personalizadas. Estos son los casos donde
interesa desarrollar scripts de migracin genricos y
crear una solucin para automatizar su ejecucin.
Ese enfoque genrico puede ser especialmente eficaz si va a recorrer varias sesiones de prueba y
desea migrar una copia nueva antes de cada sesin.
Como enumeramos a continuacin, el siguiente
es un conjunto de acciones tpico para este tipo de
procedimiento de migracin simplificada:
Backup de la Base de Datos para migrar
desde la instancia original.
Restaurar base de datos a migrar en la instancia de destino.
Actualizar las asignaciones.

The SolidQ Journal, Febrero 2011 www.solidq.com/sqj

49

Comprobacin de consistencia de la base de


datos respecto a la pureza de los datos.
Establecer nivel de verificacin de pgina (por
ejemplo, CHECKSUM).
Nivel de compatibilidad de base de datos para
que coincida con la versin de la instancia de
destino (por ejemplo, 100).
Estadsticas de actualizacin.
Eliminar los esquemas hurfanos (esquemas
creados automticamente para cada usuario
de la base de datos para mantener la compatibilidad, pero no los objetos pertenecientes a
ellos).
Tenga en cuenta que algunas de estas acciones
se aplicarn estrictamente a las bases de datos
migradas desde SQL Server 2000 (s, todava hay
gente con bases de datos que se ejecuta en SQL
Server 2000).
Por ejemplo, la comprobacin de coherencia
mediante la opcin DATA_PURITY de DBCC
CHECKDB puede hacerse una sola vez al migrar
desde 2000. Esa informacin de que ha ejecutado
una vez se marca entonces internamente en la base
de datos y, a partir de SQL Server 2005, dichos controles se realizan automticamente durante DBCC
CHECKDB habituales.
Si desea saber ms acerca de los controles de
pureza de datos, le recomendamos que lea el artculo de Knowledge Base 923247 titulado Troubleshooting DBCC error 2570 in SQL Server 2005.
Otro ejemplo es utilizar DBCC UPDATEUSAGE
para actualizar el uso de la asignacin.

Un enfoque combinado
En la mayora de los casos, las secuencias de comandos de migracin se pueden ser desarrollar completamente con PowerShell o con T-SQL; sin embargo,
ambos tienen sus fortalezas y sus debilidades.
Por ejemplo: en T-SQL que necesitemos lidiar
con la concatenacin de cadenas para crear un
comando de restauracin si es necesario mover la
parte fsica a diferentes discos/directorios; en
PowerShell directamente no podemos emitir una
accin de verificacin de coherencia con pureza de
datos contra SMO.
Adems, uno ya puede tener sus secuencias de
comandos de T-SQL bien probadas y slo se desea
automatizar algunas otras acciones a travs de
PowerShell. Cualquiera que sea la razn, vamos a
ver cmo podemos aprovechar ambos entornos de
comandos para lograr nuestro objetivo.
La idea es crear un script de PowerShell para
cada base de datos que se desea migrar, y esta
secuencia de comandos se implementar las operaciones de backup y restore y, a continuacin, ejecutar una secuencia de comandos T-SQL para finalizar la migracin.

La secuencia de comandos
de migracin en PowerShell
En primer lugar, debe definir qu ensamblados
deben ser cargados y un controlador de error genrico para atrapar a nivel global las excepciones no
controladas:

Listado 1
#region Load Assemblies and Global Error Handling
[System.Reflection.Assembly]::LoadWithPartialName( `
Microsoft.SqlServer.SMO) | Out-Null;
[System.Reflection.Assembly]::LoadWithPartialName( `
Microsoft.SqlServer.SMOExtended) | Out-Null;
# Simple global exception handling to see SQL Server errors
trap {
$Exc = $_.Exception;
while ( $Exc.InnerException )
{
$Exc = $Exc.InnerException;
Write-Warning ((generic trap) + $Exc.Message);
};
break;
};
#endregion

The SolidQ Journal, Febrero 2011 www.solidq.com/sqj

thesolidqjournal
database administration

50

A continuacin, puede continuar definiendo


algunos controladores para aadir feedback acerca
de la copia de seguridad y restaurar el progreso de
las operaciones:

alguno, que contiene el tpico mensaje que indica


el xito del proceso. En estos ejemplos, se puede
ver en el listado 3.

Listado 2
#region Event Handlers
$PercentCompleteHandler = `
[Microsoft.SqlServer.Management.Smo.PercentCompleteEventHandler] `
{
Write-Host ([string]$_.Percent + percent processed.);
};
$CompleteHandler = `
[Microsoft.SqlServer.Management.Common.ServerMessageEventHandler] `
{
Write-Host $_.Error.Message;
};
#endregion

Listado 3
BACKUP DATABASE successfully processed 665 pages in 0.415 seconds (12.518 MB/sec).
RESTORE DATABASE successfully processed 665 pages in 0.580 seconds (8.957 MB/sec).

Estos controladores son llamados directamente por SMO y vamos a implementar una notificacin de progreso simple, como la proporcionada
por SSMS o sqlcmd al lanzar la copia de seguridad
o la restauracin desde T-SQL. Tenga en cuenta
que el controlador de finalizacin simplemente
enva el mensaje de error habitual si no hay error

El siguiente paso es escribir una funcin genrica para conectarse a una instancia de SQL Server,
listado 4.
Se utiliza esta funcin para conectarse tanto a la
instancia de origen como a la de destino. Tenga en
cuenta que es compatible con los mtodos de
autenticacin de Windows y SQL Server (Listado 4).

Listado 4
#region Functions definition
function Get-SQLInstance($InstanceName, $Login, $Password)
{
$SQLInstance = New-Object Microsoft.SqlServer.Management.Smo.Server `
$InstanceName;
if ($Login -eq $null) {
$SQLInstance.ConnectionContext.LoginSecure = $true;
}
else {
$SQLInstance.ConnectionContext.LoginSecure = $false;
$SQLInstance.ConnectionContext.Login = $Login;
$SQLInstance.ConnectionContext.Password = $Password;
};
# Force connection to get an early error message
$SQLInstance.ConnectionContext.Connect();
return $SQLInstance;
};

The SolidQ Journal, Febrero 2011 www.solidq.com/sqj

51

Otra funcin generalizada que necesitar es una


que haga la copia de seguridad de las bases de
datos a migrar:

A modo de convenio, el nombre de la copia de


seguridad se deriva simplemente del nombre de
base de datos agregando el sufijo bak.

Listado 5

function DatabaseFullBackup ($SQLInstance, $DatabaseName, $BackupPath)


{
$Backup = New-Object Microsoft.SqlServer.Management.Smo.Backup;
$Backup.Action = Database;
$Backup.Database = $DatabaseName;
$Backup.Initialize = $true;
$Backup.CopyOnly = $true;
$Backup.Devices.AddDevice($BackupPath + \ + $DatabaseName + .bak `
, File);
$Backup.add_PercentComplete($PercentCompleteHandler);
$Backup.add_Complete($CompleteHandler);
$Backup.SqlBackup($SQLInstance)
};

Esta funcin acepta tres parmetros: la instancia


de SQL Server que aloja la base de datos que se
migra, el nombre de la base de datos y una ruta para
almacenar la copia de seguridad. Esta ruta puede
ser una ruta de acceso a un directorio/disco local o
una ruta de acceso UNC a un directorio compartido.
Lo importante a recordar es que el motor de SQL
Server que ejecuta el comando de copia de seguridad, debe tener los permisos adecuados para acceder a la ruta de acceso.

Adems, debe tener en cuenta que estamos


haciendo una copia de seguridad Slo copia para
no romper cualquier procedimiento de mantenimiento de copia de seguridad ya existente.
Por ltimo, necesita otra funcin generalizada
para restaurar la base de datos (listado 6). Esta funcin consta de cinco parmetros: la instancia de
SQL Server que alojar la base de datos migrada, el
nombre de la base de datos, la ruta de acceso para
la copia de seguridad creada por la funcin de base

Listado 6

function RestoreDatabaseFromFullBackup ($DestinationSQLInstance, $DatabaseName `


, $BackupPath, $DataFilesPath, $LogFilesPath)
{
$Restore = New-Object Microsoft.SqlServer.Management.Smo.Restore;
$Restore.FileNumber = 1;
$Restore.Devices.AddDevice($BackupPath + \ + $DatabaseName + .bak`
, File);
foreach ($File in $Restore.ReadFileList($DestinationSQLInstance))
{
$NewFile = New-Object Microsoft.SqlServer.Management.Smo.relocatefile;
$NewFile.LogicalFileName = $File.LogicalName;
#Primary Data File

The SolidQ Journal, Febrero 2011 www.solidq.com/sqj

thesolidqjournal
database administration

if
{

52

($File.FileID -eq 1 -and $DataFilesPath -ne )


$NewFile.PhysicalFileName = ($DataFilesPath + \ + $DatabaseName `
+

_ + $File.LogicalName + .mdf);
}
#Secondary Data File
elseif
($File.Type -eq D -and $DataFilesPath -ne )
{
$NewFile.PhysicalFileName = ($DataFilesPath + \ + $DatabaseName`
+
_ + $File.LogicalName + .ndf);
}
#Log File
elseif
($File.Type -eq L -and $LogFilesPath -ne )
{
$NewFile.PhysicalFileName = ($LogFilesPath + \ + $DatabaseName `
+
_ + $File.LogicalName + .ldf);
};
if ($NewFile.PhysicalFileName -ne $null) {
[void]$Restore.RelocateFiles.add($Newfile);
};
};
$Restore.Database = $DatabaseName;
$Restore.ReplaceDatabase = $true;
$Restore.NoRecovery = $false;
$Restore.Action = Database;
$Restore.add_PercentComplete($PercentCompleteHandler);
$Restore.add_Complete($CompleteHandler);
$Restore.SqlRestore($DestinationSQLInstance);
};
#endregion

de datos-FullBackup, una ruta para archivos de


datos y una para los archivos de registro.
Una vez ms, la convencin explicada antes
deriva el nombre del conjunto de copia de seguridad. Otra simplificacin es que estamos pasando
todos los archivos de datos a un directorio de destino nico y todos los archivos de registro a otro
directorio al restaurar la base de datos.
Con estos bloques de construccin iniciales, ahora
puede escribirse la secuencia principal para automatizar la migracin de bases de datos: Listado 7.
La secuencia de comandos es bastante explicativa, pero hay algunas cosas que sealar.

Preparar y probar un
procedimiento de migracin
slido es importante, y las
secuencias de comandos
pueden ser muy tiles para
automatizar parte del proceso.

The SolidQ Journal, Febrero 2011 www.solidq.com/sqj

Consulting

thesolidqjournal
database administration

54

Listado 7
Script 1 Database Migration.ps1
Load Assemblies and Global Error Handling
Event Handlers
Functions definition
#region Main
#Parameters
$SourceSQLInstanceName = localhost\PROD1;
$DestinationSQLInstanceName = localhost\PROD2;
$BackupPath = \\M6500\Temp\;
$DataFilesPath = D:\MSSQL.PROD02\DATA;
$LogFilesPath = D:\MSSQL.PROD02\DATA;
$DatabaseNames = AdventureWorksLT, AdventureWorksDW, AdventureWorks;
#Uncomment to add sqlcmd path
#$env:Path += ;C:\Program Files\Microsoft SQL Server\100\Tools\Binn
#Main
$SourceSQLInstance = Get-SQLInstance $SourceSQLInstanceName;
$DestinationSQLInstance = Get-SQLInstance $DestinationSQLInstanceName;
foreach ($DatabaseName in $DatabaseNames)
{
Write-Host (`nBackup database [ + $DatabaseName + ]);
DatabaseFullBackup $SourceSQLInstance $DatabaseName $BackupPath;
Write-Host (`nRestore database [ + $DatabaseName + ]);
RestoreDatabaseFromFullBackup $DestinationSQLInstance $DatabaseName `
$BackupPath $DataFilesPath
$LogFilesPath;
Write-Host (`nExecuting post-migration script for database [`
+ $DatabaseName + ]);
$ScriptPath = Split-Path -Parent $MyInvocation.MyCommand.Path;
sqlcmd.exe -S $DestinationSQLInstanceName `
-i $ScriptPath/Script 2 Post-Migration Actions.sql `
-v DatabaseName=$DatabaseName `
-o $ScriptPath/post-migration.log;
};
#endregion

La secuencia de comandos principal llama, mediante


la utilidad de lnea de comandos sqlcmd.exe, a una
secuencia de comandos T-SQL que contiene las acciones para ser ejecutadas despus de la migracin.

Como queremos que la secuencia de comandos


T-SQL sea genrica, es decir, no vinculada a una
base de datos determinada, vamos a utilizar variables de secuencias de comandos sqlcmd dentro de

The SolidQ Journal, Febrero 2011 www.solidq.com/sqj

55

la secuencia. Una manera de asignar valores a variables de secuencias de comandos sqlcmd es utilizar
el parmetro v, como se muestra en la secuencia
principal.
Suponiendo que la secuencia de comandos TSQL est en el mismo directorio que el de PowerShell, utilizamos la propiedad $MyInvocation.MyCommand.Path y el CmdLet Split-Path para obtener la
ruta de acceso a concatenar con el nombre del script
antes de pasarlos a la utilidad sqlcmd.exe. La misma
ruta se utiliza tambin para el archivo de registro
generada y pasada mediante el parmetro o.
Puede ocurrir, por alguna razn, que no tenga el
directorio de la utilidad sqlcmd.exe en la variable de
entorno PATH, obligando as a especificar tambin la
ruta para el comando. En su lugar, puede quitar el
comentario en el script y aadir el directorio siguiente:

$env:Path += ;C:\Program Files\Microsoft SQL Server\100\Tools\Binn

Encontrar la solucin completa en Script 1:Database Migration.ps1.

El script de migracin de T-SQL


Como dijimos al principio, queremos mantener algunas actividades post-migracin en una secuencia de
comandos T-SQL. Para este escenario simplificado,
queremos ejecutar las siguientes acciones: comprobacin de la coherencia de la base de datos, actualizacin de uso de la asignacin, configuracin del
nivel de verificacin de la pgina, configuracin del
nivel de compatibilidad de la base de datos, actuali-

Listado 8

ALTER DATABASE [$(DatabaseName)] SET SINGLE_USER WITH ROLLBACK IMMEDIATE;


DBCC UPDATEUSAGE([$(DatabaseName)]);
DBCC CHECKDB([$(DatabaseName)]) WITH DATA_PURITY;
ALTER DATABASE [$(DatabaseName)] SET PAGE_VERIFY CHECKSUM;
ALTER DATABASE [$(DatabaseName)] SET COMPATIBILITY_LEVEL = 100;
USE
EXEC

[$(DatabaseName)];
sp_updatestats;

DECLARE #schemas CURSOR READ_ONLY


FOR
SELECT
S1.NAME
FROM
sys.schemas AS S1
WHERE
S1.NAME NOT IN (dbo, guest, INFORMATION_SCHEMA, sys)
AND
S1.SCHEMA_ID < 16384
AND
NOT EXISTS (
SELECT
*
FROM
sys.objects AS O1
WHERE
S1.SCHEMA_ID = O1.SCHEMA_ID
);
DECLARE @schema_name sysname;
OPEN #schemas;
FETCH NEXT FROM #schemas INTO @schema_name;
WHILE (@@fetch_status <> -1)

The SolidQ Journal, Febrero 2011 www.solidq.com/sqj

thesolidqjournal
database administration

56

BEGIN
IF (@@fetch_status <> -2)
BEGIN
DECLARE @sqlstmt nvarchar(max);
SET
@sqlstmt = DROP SCHEMA [ + @schema_name + ];
EXEC
sp_executesql @sqlstmt;
END
FETCH NEXT FROM #schemas INTO @schema_name;
END
CLOSE #schemas;
DEALLOCATE #schemas;

zacin de las estadsticas y eliminar esquemas hurfanos.


Para llevar a cabo estas actividades, podra utilizar el siguiente cdigo T-SQL, Listado 8, pgina 55.
Como se puede ver, el cdigo utiliza la variable
de secuencias de comandos sqlcmd $(DatabaseName) para que pueda utilizarse por varias bases de
datos, simplemente asignando el nombre a la base
de datos a la variable antes de ejecutarla. Por ejemplo, mediante el parmetro v con la utilidad
sqlcmd.exe, como ha visto en la seccin anterior.
Puede encontrar un script de T-SQL ms completo, que incluye comandos para imprimir el progreso, en Script 2 Post-Migration Actions.sql.

Comprobar los registros de migracin


Los comandos de DBCC y el procedimiento almacenado del sistema sp_updatestats producen una

salida muy detallada. Esto es bueno, porque deseamos estar seguros de obtener toda la informacin
que necesitamos. Sin embargo, al automatizar una
migracin para varias iteraciones de prueba puede
ser tedioso hacerlo cada vez tener que ir a travs de
los registros de ejecucin T-SQL para ver si hay
algn error.
Para facilitar este paso, puede crearse un script
rpido de PowerShell que analice los registros basados en algunos patrones conocidos, como en los
ejemplos que mostramos en el listado 9.
La secuencia de comandos recorre todos los
archivos con el sufijo log en el nombre de archivo,
en un directorio determinado. Para cada archivo, primero busca la anteltima cadena en la salida generada por DBCC CHECKDB, para ver si se produjeron
errores de informacin en cualquier asignacin, o
errores de consistencia, y, a continuacin, busca
errores genricos de SQL Server.

Listado 9
Script 3 Check Post-Migration Logs.ps1
#region Regex search string definitions
$SearchDBCC = [regex] (CHECKDB found (?<AllocErr>\d*) allocation errors and `
+ (?<ConsErr>\d*) consistency errors in database (?<DBName>.*)\.);
$SearchSQLError = [regex] (Msg (?<ErrNum>\d*), Level (?<ErrLevel>\d*)`
+ , State (?<ErrState>\d*), Server (?<ErrServer>.*)`
+ , Line (?<ErrLine>\d*)\x0d\x0a(?<ErrMsg>.*)\x0d\x0a);
#endregion
dir D:\temp\*.log |
% {
Write-Output `n******************************************************;
Write-Output Searching for consistency/allocation errors in log $_
$TotalErrors = 0;

The SolidQ Journal, Febrero 2011 www.solidq.com/sqj

57

$log = [io.file]::ReadAllText($_);
$match = $SearchDBCC.Match($log);
while ($match.Success) {
if ($match.Groups[AllocErr].Value -ne 0 `
-or $match.Groups[ConsErr].Value -ne 0) {
Write-Output (Database + $match.Groups[DBName].Value `
+ allocation errors + $match.Groups[AllocErr].Value `
+ consistency errors + $match.Groups[ConsErr].Value);
$TotalErrors = [int]$match.Groups[AllocErr].Value `
+ [int]$match.Groups[ConsErr].Value;
};
$match = $match.NextMatch();
};
Write-Output ******************************************************;
Write-Output `Searching for generic SQL Server errors in log $_
$match = $SearchSQLError.Match($log);
while ($match.Success) {
Write-Output $match.Value;
$TotalErrors++;
$match = $match.NextMatch();
};
Write-Output ******************************************************;
if ($TotalErrors -eq 0) {
Write-Output No errors found.;
};
};

Listado 10
******************************************************
Searching for consistency/allocation errors in log D:\temp\post-migration.log
Database Northwind allocation errors 0 consistency errors 4
******************************************************
Searching for generic SQL Server errors in log D:\temp\post-migration.log
Msg 8928, Level 16, State 1, Server M6500\PROD2, Line 19
Object ID 149575571, index ID 1, partition ID 72057594039697408, alloc unit ID 72057594040942592 (type In-row data):
Page (1:283) could not be proce
ssed. See other errors for details.
Msg 8939, Level 16, State 98, Server M6500\PROD2, Line 19
Table error: Object ID 149575571, index ID 1, partition ID 72057594039697408, alloc unit ID 72057594040942592 (type
In-row data), page (1:283). Test
(IS_OFF (BUF_IOERR, pBUF->bstat)) failed. Values are 12584969 and -4.
Msg 8980, Level 16, State 1, Server M6500\PROD2, Line 19
Table error: Object ID 149575571, index ID 1, partition ID 72057594039697408, alloc unit ID 72057594040942592 (type
In-row data). Index node page (1
:309), slot 0 refers to child page (1:283) and previous child (0:0), but they were not encountered.
Msg 8978, Level 16, State 1, Server M6500\PROD2, Line 19
Table error: Object ID 149575571, index ID 1, partition ID 72057594039697408, alloc unit ID 72057594040942592 (type

The SolidQ Journal, Febrero 2011 www.solidq.com/sqj

thesolidqjournal
database administration

58

In-row data). Page (1:310) is mi


ssing a reference from previous page (1:283). Possible chain linkage problem.
******************************************************

Otherwise the output will be similar to the following:


******************************************************
Searching for consistency/allocation errors in log D:\temp\migration.log
******************************************************
Searching for generic SQL Server errors in log D:\temp\migration.log
******************************************************
No errors found.

Si se detectan errores, se informa de ello, tal y


como aparece en la siguiente pgina de ejemplo,
Listado 10, pagina 57.
Puede encontrar este script en Script 3 Check
Post-Migration Logs.ps1.

Conclusiones
Este mes hemos visto cmo utilizar una mezcla de
secuencias de comandos PowerShell y T-SQL, para
ayudarnos a automatizar la migracin de bases de
datos desde instancias de SQL Server antiguas a
otras ms recientes.
Recuerde siempre que el cdigo que figura en el
presente artculo es slo un ejemplo para mostrar
cmo se puede aprovechar PowerShell y no es adecuado para la produccin o uso de propsito general. Como de costumbre, hemos tenido que introducir algunas simplificaciones para mantener el artculo a un tamao razonable.
Por ejemplo, en el anlisis de los registros, confiamos en formatos de mensaje de error fijo. Si, por
cualquier la razn, esto cambia, se corre el riesgo de
pasar por alto algunos errores. Adems, ignoramos
deliberadamente los mensajes de Service Broker.
Por lo tanto, puede que desee crear una solucin
ms slida para su uso en produccin.
Otro ejemplo es el conjunto de acciones postmigracin. En un escenario de migracin real, normalmente es necesario llevar a cabo ms acciones,
algunas de las cuales dependen tambin de lgica
condicional.
La migracin es un tema muy interesante y hay
varias reas donde puede utilizarse PowerShell para

automatizar las cosas por lo que podemos volver a


ella en el futuro.
Hasta entonces, nos gustara saber su opinin, especialmente sobre qu temas le gustara
leer en nmeros sucesivos. Escrbanos a TheJournal@solidq.com.

Acerca de los Autores


Herbert Albert (twitter) es Mentor y Administrador General de Solid Quality Mentors
Europa Central. Es MCSE, MCDBA, y MCT
en SQL Server, Herbert es un entrenador formador y consultor de SQL Server cuyo
conocimiento cubre un amplio espectro de
tecnologas de Microsoft. Trabaja de forma muy cercana con
Microsoft Austria en varios eventos de entrenamientoformacin. Sigue a Herbert en twitter: @AlbertHerbert

Gianluca Hotz twitter) es Mentor con


Solid Quality Mentors, especializado en
arquitectura, Alta disponibilidad, mejora de
rendimiento, y diseo de bases de datos SQL
Server. Como entrenador formador y autor,
Gianluca ha administrado impartido cursos
de SQL server Server para elun enorme CTEC italiano. Tambin
apoya a Microsoft Italia en el campo como speaker en conferencias locales. Gianluca fund el Grupo de Usuarios de SQL
Server, actualmente funge como Vicepresidente, y asiste a
otros usuarios en grupos de noticias. Ha sido MVP de Microsoft
SQL Server desde 1998. Sigue a Gianluca en twitter: @glhotz

The SolidQ Journal, Febrero 2011 www.solidq.com/sqj

You might also like