You are on page 1of 3

Detecting Orphaned Objects in Production

BY BRYAN MAY 30, 2011

One thing that has always annoyed me about MicroStrategy Object


Manager is its insistence to migrate schema objects with even the
slightest excuse. In the same vein as Quantum Mechanics, when
things get small they get weird, the same is true in the
MicroStrategy metadata. The Metadata Dependency table keeps all
of the relationships between objects, for example, a Report is a
parent of the Metric that is added to it. But this rule breaks down
with Attributes and Tables. An Attribute is a parent of its Table, but
a Table is also a parent of its Attributes. This strangeness creates
what I call Schema Spidering in Object Manager, where effectively
everything is related to everything some way or the other. This
means if you create a new attribute, and then migrate a completely
unrelated report, Object Manager will find a way to get that new
attribute over and you (usually) cant prevent it. There are some
settings to prevent this spidering, but for various reasons I dont
feel comfortable disabling them, so I deal with the freeloaders to
Production.
The problem this causes is not only that you could end up with
Developmental and untested schema changes in Production, but
inevitably youll end up with objects in Production that no longer
exist in Development (Orphans). This could lead to inconsistant
testing results or worse. Today, Ill share a quick script to detect
these orphans so that you can monitor them and take action.
This SQL script is written based on a MS-SQL Metadata, and should
be easy to adjust for different platforms. In essence, it will compare
two projects (Production vs Development) and list objects that are in
Production and not Development. You could wrap this into a
Freeform SQL Report and subscribe it to yourself to receive

notifications of when this occurs, and then take actions on those


objects.

drop table #folders


select o.project_id, p.object_name as project_name, o.project_id as parent, p.object_name
as parent_name, o.object_id as folder, o.object_name as folder_name
into #Folders
From dssmdobjinfo o
join dssmdobjinfo p
on o.project_id = p.object_id
join dssmdobjinfo r
on o.parent_id = r.object_id and o.project_id = r.project_id
where r.object_name in('Public Objects', 'Schema Objects') and o.PROJECT_ID = 'PRODUCTION
PROJECT GUID'

while @@rowcount > 0


begin
insert into #Folders
select o.project_id, f.project_name as project_name, o.parent_id as parent, p.object_name
as parent_name, o.object_id as folder, o.object_name as folder_name
from dssmdobjinfo o
join #folders f
on o.project_id = f.project_id and o.parent_id = f.folder
join dssmdobjinfo p
on o.parent_id = p.object_id and o.project_id = p.project_id
where o.object_id not in(select distinct folder from #folders)
and o.object_type = 8 and o.subtype = 2048 and o.hidden = 0
end

select p.OBJECT_TYPE, p.OBJECT_NAME, p.DESCRIPTION, p.CREATE_TIME, f.folder_name


from DSSMDOBJINFO p
join #folders f
on p.PARENT_ID = f.folder

left join (select * FRom DSSMDOBJINFO where PROJECT_ID = 'DEVELOPMENT PROJECT GUID') d
on p.OBJECT_ID = d.OBJECT_ID
where p.PROJECT_ID = 'PRODUCTION PROJECT GUID'
and d.OBJECT_ID is null

The first 2 sections of the script are used to build a list of folders
under Public Objects and Schema Objects. The reason youll want to
do this is because youll surely get lots of Orphan hits for users
objects in My Reports, so this is the best way Ive found to isolate
Public/Schema Objects only.
Once we have that, we can join it to the list of objects in Production,
and then compare that to the list of objects in Development. The
resulting list is our culprits!
Unfortunately, the Metadata does not provide a lookup table for
Object Types, and you may want to adjust some of the things youre
considering Orphaned (for example, exclude Shortcut objects). It
may also make the report easier to take action on if it told you an
orphan was a Report instead of 3. To implement this, simply
create your own lookup table for Object Type in your metadata, and
add it to the 3rd part of the query. You can obtain a list of Object
Types from this Tech Note.
UPDATE: Object IDs are handled differently in 9.2+, so be sure to
check out Changes to Object IDs in 9.2

You might also like