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

Cálculos de tiempo personalizados en SSAS Multidimensional

Si para ciertas cuentas no queremos sumar en los cálculos temporales, sino hacer otra operación, por ejemplo, la media, podemos definir una columna (TBAverage) que para cada cuenta indique si suma (0) o hace la media (1). La usaremos en el cubo como una medida que comprobaremos para cada nivel para detectar si esa cuenta debe sumar o hacer la media para los cálculos temporales.

Despliegue de Proyectos en Integration Services 2012

En entradas anteriores hemos revisado las características que ofrece el nuevo modelo de servidor de Integration Services, que se basa en Proyectos y Entornos en lugar de Paquetes y Configuraciones.En SQL Server 2012 se mantendrá la compatibilidad con el modelo de despliegue anterior, basado en paquetes, con la denominación Package Deployment Model. Los procedimientos para realizar despliegues en este modo no han variado desde versiones anteriores por lo que nos centraremos en el modelo de despliegue de proyectos Project Deployment Model.