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

Autenticación Integrada en Azure Database con SSIS

En muchos escenarios se nos presenta la necesidad de usar autenticación integrada para acceder a los orígenes de datos necesarios para alimentar nuestro sistema analítico. Con el uso cada vez más extendido de Azure, como al menos parte de nuestra infraestructura, algunos de estos orígenes van a estar alojados en bases de datos en Azure. En este caso vamos hablar de un error real que hemos tenido en la configuración y uso de la autenticación integrada contra bases de datos Azure con SSIS.
Leer más

Super SSIS, tu nuevo superhéroe

¿Tus procesos ETL con SSIS rinder a niveles humanos? ¿Necesitas más velocidad, gestionar más datos, mejor performance? ¿No tienes tiempo de esperar al último hijo de Krypton para que ejecute tus DataFlow? En esta sesión veremos técnicas de optimización en entornos modernos (¡estamos en 2017!) para que lleves tus paquetes SSIS al siguiente nivel... ¡el nivel de los superhéroes!