La verdad es que es un poco fastidioso (por definirlo suavemente), que las funciones de sistema object_name, object_id, objectproperty, etc. estén bajo el ámbito de una base de datos…A mí me gustaría una función de este estilo: objec_name (db_id, object_id) , y me devolviera el nombre del identificador de objeto object_id, de la base de datos db_id.

Esto está tomando otros aires a partir de la versión 2005 de SQL Server, y ahora con las nuevas DMVs, el ámbito es más a nivel de instancia de SQL Server; por ejemplo, la DMV sys.dm_db_sys.dm_db_index_usage_stats, o la DMF sys.dm_db_index_physical_stats están definidas a nivel de instancia (fíjate que tiene como argumento el identificador de base de datos.

Entonces, ¿por qué no una función de sistema como object_name, cuyo ámbito sea la base de datos?

mientras eso no aparezca, podremos utilizar el siguiente código que explico a continuación:

la idea es muy simple: un cursor que se recorra todas las bases de datos de la instancia de SQL Server, y ejecutar una sentencia sql dinámica del siguiente formato:

INSERT INTO ##objetos (dbid, database_name, objectid, object_name, indexid, index_name, xtype)

SELECT dbid, db_name, so.id, so.name, si.indid, si.name, so.xtype FROM

<base_datos>..sysobjects so join

<base_datos>..sysindexes si on so.id = si.id WHERE so.id > 0

 

 

No hemos inventado la rueda… aunque estoy seguro que le podrás sacar provecho… adaptala a tu necesidad, y comentame si te sirve 😉

— obtener todos los dbid, objectid

SET NOCOUNT ON

GO

IF NOT OBJECT_ID (‘tempdb.dbo.##objetos’) IS NULL

 

DROP TABLE ##objetos

CREATE TABLE ##objetos (dbid INT, database_name SYSNAME, objectid INT, object_name SYSNAME, indexid INT, index_name SYSNAME NULL, xtype char(2))

DECLARE c1 CURSOR READ_ONLY

FOR SELECT dbid, name FROM master..sysdatabases where dbid >= 5

DECLARE @db_id SMALLINT

, @db_name SYSNAME

OPEN c1

FETCH NEXT FROM c1 INTO @db_id, @db_name

 

WHILE (@@fetch_status <> 1)

BEGIN

 

IF (@@fetch_status <> 2)

BEGIN

DECLARE @sql NVARCHAR(4000)

SET @sql = ‘INSERT INTO ##objetos (dbid, database_name, objectid, object_name, indexid, index_name, xtype) ‘

SET @sql = @sql + ‘SELECT ‘ + CAST(@db_id AS SYSNAME) + ‘, ”’ + CAST(@db_name AS SYSNAME)

+ ”’, so.id, so.name, si.indid, si.name, so.xtype FROM ‘ +

@db_name + ‘..sysobjects so join ‘ +

@db_name + ‘..sysindexes si on so.id = si.id WHERE so.id > 0’

EXEC (@sql)

END

FETCH NEXT FROM c1 INTO @db_id, @db_name

END

CLOSE c1

DEALLOCATE c1

 

 

Ahora ya solo quedaría consulta la tabla rellena:

SELECT * FROM ##objetos

 

Por cierto, aplicable para cualquier versión de SQL Server… para 2005 sería didáctico hacerlo con las nuevas DMVs (sys.tables, sys.objects, …), pero bueno, lo dejamos como ejercicio 🙂

0 Shares:
Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

You May Also Like
Leer más

BI E2E en Azure

La nube ha abierto en los últimos años escenarios de análisis que antes eran impensables. Sistemas BI levantados y corriendo en minutos en vez de meses, alta disponibilidad al alcance de un botón, pagar únicamente por lo que consumimos... En esta sesión veremos las diferentes opciones que tenemos en Azure para conseguir mover nuestra infraestructura BI a la nube y aprovecharnos de sus ventajas.

Sobre la nueva certificación MCDBA

Si has leido el mensaje Microsoft Certified Database Administrator for Yukon de Clemens Reijnen , ya sabres que Microsoft está cambiando esta certificación para hacerla m;as cercana a la realidad de las tareas que los administradores de bases de datos realizan cada día en su puesto de trabajo.