November 6, 2006 at 9:39 am
November 6, 2006 at 9:43 am
There are no reliable (100%) way of getting that information in sql server.
The best you can do is scan the syscomments table and try to find them by yourself. I guess you could recompile all hits you find... even if you recompile more objects than needed, at least you get 'em all.
November 6, 2006 at 9:45 am
So its psooible in 2005 but not 2000?
November 6, 2006 at 9:49 am
Check out the sysdepends table in 2000.
As I said it is not reliable (you could miss quite a few objects). I have no idea if it is more reiable on 2005. That's why I suggested the syscomments scan on the text column (still not 100% but very close).
November 6, 2006 at 9:52 am
Thanks - How does SQL server return the dependencies list if you try and delete the object?
November 6, 2006 at 9:58 am
I guess it deletes the corresponding rows in the dependancies table when you delete an object. But the problem comes when you recreate objects, all dependancies are deleted, and only some are recreated. So after a while you start to miss a lot of 'em. I never got a full proof workaround for this one... and I don't think anyone exists !
November 6, 2006 at 10:02 am
OK - Ta
November 6, 2006 at 1:57 pm
in SQL 2000 you can run sp_MSdependencies with no parameters to get the list of objects in a order of hierarchy, but it's not perfect if you have a circular fk structure, like TABLE A referenced TABLE B, but TABLE B also references Table A (typical when you are realating users or entities to each item
Of course the results are based on foreign keys and sysdepends, so if a dependancy is missing, it might be incorrect.
so most of the time, the list of items in that resultset is the order in which to create the objects.
I created this because of those rare circular references, this might help as well, as far as getting the hierarchy of tables for foreign keys; This skips around Functions and procedures:
SET NOCOUNT ON
DECLARE
@Level INT,
@MovedToNewLevel INT,
@sql varchar(1024),
@err varchar(125),
@LastBatch int
CREATE TABLE #Hierarchy
(FKLevel INT,
TblName VARCHAR(100),
id Numeric
)
-- Populate the table
INSERT INTO #Hierarchy
select 0 AS 'FKLevel', name as 'TblName',id
FROM sysobjects where xtype='U' and
id not in (select rkeyid from sysforeignkeys) and
id not in (select fkeyid from sysforeignkeys)
INSERT INTO #Hierarchy select 1 AS 'FKLevel', name as 'TblName',id
FROM sysobjects where xtype='U' and
id not in (select id from #Hierarchy) and
id in (select rkeyid from sysforeignkeys) and
id not in (select fkeyid from sysforeignkeys)
INSERT INTO #Hierarchy select 2 AS 'FKLevel', name as 'TblName',id
FROM sysobjects where xtype='U' and
id not in (select id from #Hierarchy) and
id in (select fkeyid from sysforeignkeys)
-- Set the variables
set @Level=2
set @MovedtoNewLevel=1
WHILE @MovedtoNewLevel <> 0
BEGIN
set @LastBatch=@MovedtoNewLevel
set @sql='update #Hierarchy set FKLevel = FKLevel + 1 where FKLevel=' + CAST(@Level as varchar) + ' and'
set @sql=@sql + ' id in (select fkeyid from sysforeignkeys where fkeyid<>rkeyid and'
set @sql=@sql + ' rkeyid in (select id from #Hierarchy where FKLevel=' + CAST(@Level as varchar) + ' ))'
exec(@sql)
SET @MovedtoNewLevel = @@Rowcount
set @err='#ID''s yet to be processed :' + convert(varchar,@MovedtoNewLevel)
--'BANDAID TO WORK AROUND CIRCULAR FK REFERENCES, WHERE EVENTUALLY,
--TABLEA REFERS TO TABLEQ AND TABLEQ REFERS TO TABLEA
if @LastBatch=@MovedtoNewLevel
BEGIN
select top 1 @err= TblName from #Hierarchy WHERE FKLevel IN(SELECT MAX(FKLevel) FROM #Hierarchy )
set @err = 'possible Circular FK''s found, arbitrarily changing ' + @err + ' to break circular reference.'
--RAISERROR (@err,1,1)
set rowcount 1
UPDATE #Hierarchy SET FKLevel = FKLevel - 1
WHERE FKLevel IN(SELECT MAX(FKLevel) FROM #Hierarchy )
set rowcount 0
END
--RAISERROR(@ERR,1,1)
SELECT @Level = @Level + 1
End
select * from #Hierarchy order by FKLEVEL
HTH
Lowell
November 7, 2006 at 3:24 am
Thanks Lowell - I'm not to sure I need this solution - and since a beginner at this I don't reall understand what is going on there!
Having had a little think about the problem - Lets say I have views A, B, C , D , E
Where B is a view of A, C is a view of B etc etc
Lets say i changed A - I would want to refresh B - E if I looped thru B-E How would I ensure they were refreshed in the correct order - ie if E was freshed before B - then I am assuming the change in A wouldn't be reflcted in E?
My solution would be to loop thru B- E refreshing each 4 times - thereby ensuring all objects coorectly refreshed. ie if I was unlucky and did them purely in the wrong order n objects would take n loops to refresh them all correctly.
At the moment all I have is a view containing the view names that I want to refresh - how do I execute a loop n times thru the n objects doing a refeshview on each one each time?
Or is this just a crazy solution - at the moment I can't see another which wouldn't involve much manual intervention!
Cheers
November 7, 2006 at 6:50 am
i was originally going to post about the wonders of sp_recompile, but it didn't work as expected. I thought it recompiled dependant objects as well, causing a chain reaction, but it does not.
there's two options i can think of;
if you change your views to use schemabinding, that might do it automatically;
i would personally just be lazy and recompile all objects after i changed a table or view; it depends on your database as to whether that would slow things down when an object gets recompiled
Here's how I'd create a cursor and recompile all objects:
declare
@isql varchar(2000),
@objname varchar(64)
declare c1 cursor for select name from sysobjects where xtype in('FN','TF','V','P') order by xtype
open c1
fetch next from c1 into @objname
While @@fetch_status <> -1
begin
select @isql = 'sp_recompile @objname
select @isql = replace(@isql,'@objname',@objname)
print @isql
exec(@isql)
fetch next from c1 into @objname
end
close c1
deallocate c1
Lowell
November 7, 2006 at 9:42 am
Thanks Lowell have got that cursor thru the view names to work - only 1 problem - views which have schemabinding come back as invalid object names - I can safely ignore these views howver - how would I exclude these form the SELECT of viewnames?
Ta
November 7, 2006 at 10:05 am
yould want to use something like this:OBJECTPROPERTY(OBJECT_ID(OBJNAME), 'IsSchemaBound')=0 means false, and OBJECTPROPERTY(OBJECT_ID(OBJNAME), 'IsSchemaBound')=1 means true
so i'd use something like this for the cursor:
select name from sysobjects where xtype='V' and OBJECTPROPERTY(OBJECT_ID(NAME), 'IsSchemaBound')=0
Lowell
November 8, 2006 at 3:45 am
Thanks that works perfectly.
November 8, 2006 at 5:31 am
Sorry spoke to soon - errors out if the views are tried to refresh in the wrong order. - ie if view D is refreshed before B then get an error.
November 9, 2006 at 12:44 pm
Have you figured out a methodology to determine the order in which the views should be refreshed?
I have a similar problem, but it relates to both refreshing and creating new views. I have year specific views (related to a tax year); therefore, I would have A_2005 is built upon B_2005 which is built upon C_2005. Next year, I'll have to create a script for each view, but change the years from 2005 to 2006 (A_2006 is built upon B_2006...). Since I have hundreds and hundreds of these dependent, year specific views, I was trying to automatically generate the create SQL scripts in the correct order. I could create the text from the 2005 tables and then with any text editor change the 2005 values to 2006.
Viewing 15 posts - 1 through 15 (of 15 total)
You must be logged in to reply to this topic. Login to reply