Una de las nuevas funcionalidades que tenemos en SQL Server 2008 es la capacidad de tener servidores de administrador donde registramos otras instancias de SQL Server de forma que podamos administrarlas de forma conjunta. Una de las funcionalidades más flexibles que nos permite Management Studio 2008 es la de lanzar un script T-SQL contra todos los servidores registrados. De esta forma podemos realizar operaciones de mantenimiento, cambios en los esquemas, etc. contra N servidores de la misma forma que lo haríamos con un único servidor.Los que siguierais las distintas CTPs de SQL Server 2008 habréis detectado que el funcionamiento ha ido variando en lo que a agrupación de resultados respecta. En la versión final tenemos lo mejor de las alternativas anteriores J En algunos casos puede ser necesario realizar cambios en la configuración por defecto debido a que, por ejemplo, tratamos con bases de datos heterogéneas. Por ejemplo imaginemos que tenemos el siguiente escenario con dos servidores registrados en un servidor central:

En cada una de las instancias hemos creado previamente un par de tablas que cuya definición es ligeramente diferente en cada uno de los servidores. Si en la instancia SQL2008_2 y SQL2008_3 creamos un mismo objeto pero con diferente esquema podremos comprobar cómo el comportamiento por defecto de Management Studio nos puede dar algún problema.

SQL2008_3

CREATE TABLE [dbo].[test_esquema](

    [a] [int] NOT NULL,

PRIMARY KEY CLUSTERED

(

    [a]

))

GO

INSERT INTO [dbo].[test_esquema] VALUES (1)

GO

CREATE TABLE [dbo].[test_esquema2](

    [a] [int] NOT NULL,

PRIMARY KEY CLUSTERED

(

    [a]

))

GO

INSERT INTO [dbo].[test_esquema2] VALUES (1)

 

 

SQL2008_2

CREATE TABLE [dbo].[test_esquema](

    [a] [int] NOT NULL,

    [nombre] [varchar](50) NULL,

PRIMARY KEY CLUSTERED

(

    [a]

))

INSERT INTO [dbo].[test_esquema] VALUES (1,‘Agapito’)

GO

CREATE TABLE [dbo].[test_esquema2](

    [a] [varchar](3) NOT NULL,

PRIMARY KEY CLUSTERED

(

    [a]

))

GO

INSERT INTO [dbo].[test_esquema2] VALUES (‘1’)

GO

INSERT INTO [dbo].[test_esquema2] VALUES (‘a’)

Si lanzamos una consulta (SELECT * FROM tempdb.dbo.test_esquema) que implique diferencias de esquema desde el servidor de administración central nos encontramos con el siguiente error:

An error occurred while executing batch. Error message is: The result set could not be merged because the result schema did not match the schema from the first responding server.

Si por el contrario el número de columnas es idéntico pero tenemos diferencias en los tipos de datos nos podemos encontrar con un comportamiento bastante extraño. Por ejemplo si ejecutamos SELECT * FROM tempdb.dbo.test_esquema2 obtenemos este resultado:

¿Qué ha ocurrido con el registro con valor 1 de la instancia SQL2008_3? Parece que internamente se ha intentado realizar alguna conversión entre el entero y varchar y su resultado ha sido una cadena vacía. Esto nos da que pensar que el orden de ejecución es relevante para este tipo de efectos. Si recreamos las tablas de forma cruzada (las de la instancia 2 en la instancia 3 y viceversa) el resultado es el siguiente:

Por tanto la conclusión es que el orden de los factores sí altera el valor del producto L Del primero de los servidores se obtienen los metadatos y para el resto se realiza una conversión a dicho tipo de datos de forma acertada o no.

Este es un comportamiento un tanto inestable por lo que no se recomienda lanzar este tipo de consultas contra esquemas heterogéneos sin realizar las conversiones pertinentes en la propia operación. Por ejemplo el resultado sería correcto en el siguiente caso:

SELECT CONVERT(varchar(50),a) FROM tempdb.dbo.test_esquema2

Para el primero de los errores podríamos conseguir un workaround también comprobando si existe o no la columna y lanzando una consulta diferente en cada caso:

IF COLUMNPROPERTY (OBJECT_ID(‘tempdb.dbo.test_esquema’),‘nombre’, ‘ColumnId’) IS NULL

    SELECT a,» AS nombre FROM tempdb.dbo.test_esquema

ELSE

    SELECT * FROM tempdb.dbo.test_esquema

Finalmente comentar que existe la posibilidad de configurar esta funcionalidad para que nos devuelva los resultados sin agrupar con lo cual evitamos estos problemas con la desventaja de tener los resultados no agrupados. Para ello nos iremos a las opciones de configuración de Management Studio:

Si no disponer de los resultados agrupados no es problema configurando a false esta opción podemos ejecutar cualquiera de las consultas anteriores sin tenernos que preocupar de conversiones o workarounds:

 

Rubén Garrigós

Mentor at SolidQ
I am an expert in high-availability enterprise solutions based on SQL Server design, tuning, and troubleshooting. Over the past fifteen years, I have worked with Microsoft data access technologies in leading companies around the world.

Nowadays, I am a Microsoft SQL Server and .NET applications architect with SolidQ. I am certified by Microsoft as a Solution Expert on the Microsoft Data Platform (MSCE: Data Platform) and as a Solution Expert on the Microsoft Private Cloud (MSCE: Private Cloud). As a Microsoft Certified Trainer (MCT), I have taught multiple official Microsoft courses as well as other courses specializing in SQL Server. I have also presented sessions at official events for various Microsoft technologies user groups.
Rubén Garrigós

Latest posts by Rubén Garrigós (see all)