You can try this query, mind you that this can also list false positives in certain cases.
Query to get a list of invalid objects:
select QuoteName(OBJECT_SCHEMA_NAME(referencing_id)) + '.' + QuoteName(OBJECT_NAME(referencing_id)) AS ProblemObject,
o.type_desc,
ISNULL(QuoteName(referenced_server_name) + '.', '')
+ ISNULL(QuoteName(referenced_database_name) + '.', '')
+ ISNULL(QuoteName(referenced_schema_name) + '.', '')
+ QuoteName(referenced_entity_name) AS MissingReferencedObject
from sys.sql_expression_dependencies sed
left join sys.objects o on sed.referencing_id=o.object_id
where (is_ambiguous = 0)
and (OBJECT_ID(ISNULL(QuoteName(referenced_server_name) + '.', '')
+ ISNULL(QuoteName(referenced_database_name) + '.', '')
+ ISNULL(QuoteName(referenced_schema_name) + '.', '')
+ QuoteName(referenced_entity_name)
) IS NULL)
order by ProblemObject, MissingReferencedObject
more info can be found here
Other useful queries when you are redesigning your scheme can be this
query to find procedures that are called from others:
declare @t table (procname varchar(200), called_in varchar(200))
declare @ProcName varchar(200)
declare crProcs cursor local FAST_FORWARD READ_ONLY for
select distinct
o.name as procedure_name
from sys.sql_modules m
inner join sys.objects o ON m.object_id = o.object_id
where o.Type = 'P'
open crProcs
fetch next from crProcs into @ProcName
while @@FETCH_STATUS = 0
begin
insert into @t (procname, called_in)
select @ProcName,
o.name
from sys.sql_modules m
inner join sys.objects o ON m.object_id = o.object_id
where m.definition Like '%' + @ProcName + '%'
group by o.name
fetch next from crProcs into @ProcName
end
close crProcs
deallocate crProcs
select *
from @t t
where 1 < (select count(1) from @t t2 where t2.procname = t.procname )
query to find all objects where another object is being used:
SELECT DISTINCT
o.name AS Object_Name,
o.type_desc,
m.*
FROM sys.sql_modules m
INNER JOIN sys.objects o ON m.object_id = o.object_id
WHERE m.definition Like '%MyTableThatIWantToChangeTheScheme%'