SQLServerCentral Article

Finding Real Dependencies

,

Do you remember the differences between SQL 6.5 and SQL 2000 about creating a procedure that calls another

procedure that doesn't exist?

Server 6.5 would not allow the procedure to be created when it depends upon a

non-existing procedure.

On the other hand, SQL Server 7.0 and 2000 will allow the procedure to be

created, and the SP_DEPENDS system procedure will not report correct results.

If we run following script:

USE Northwind
go
CREATE PROCEDURE proc1 
AS exec proc2
GO
CREATE PROCEDURE proc2 
AS exec proc3
GO
CREATE PROCEDURE proc3
AS exec proc4
GO
CREATE PROCEDURE proc4 
AS exec proc5
GO
CREATE PROCEDURE proc5
AS exec proc6
GO 

We receive sql messages:

Cannot add rows to sysdepends for the current stored procedure because it depends on the missing object 'proc2'. 
The stored procedure will still be created.
Cannot add rows to sysdepends for the current stored procedure because it depends on the missing object 'proc3'. 
The stored procedure will still be created.
Cannot add rows to sysdepends for the current stored procedure because it depends on the missing object 'proc4'. 
The stored procedure will still be created.
Cannot add rows to sysdepends for the current stored procedure because it depends on the missing object 'proc5'. 
The stored procedure will still be created.
Cannot add rows to sysdepends for the current stored procedure because it depends on the missing object 'proc6'. 
The stored procedure will still be created. 

In sysdepends table will not exist dependencies for "proc(i) 

- proc(i+1)".  We can check that with this statement

 which should yield zero records.

select * from sysdepends where object_name(id) like 'proc%'

So I can't trust system table sysdepends. However, sometimes I need real information about dependencies, especially between

stored procedures, to get the real processing flow.

So I developed a sql statement to show store procedure dependencies in one

database by searching sysobjects and syscomments system tables.

At first I'm creating a recursive function which will return sp text without comments. This function erases up to 160 line comments and 160 block comments -

32 nested level of recursive function and five replacement in every function

call. We can increase this number if we need it.

CREATE Function funProcWithoutComments
(@Input VARCHAR(4000))
RETURNS VARCHAR(4000) -- tuka da se proveri
BEGIN 
DECLARE @Output VARCHAR(4000)
DECLARE @i INT
If @Input NOT LIKE '%--%' and @Input NOT LIKE '%/*%*/%'
BEGIN
SET @Output = REPLACE(@Input , CHAR(10) + CHAR(13) , '')
RETURN @Output
END
ELSE
BEGIN
SET @input = @input + char(13)
set @i = 1
while @i <= 5
begin
IF charindex('/*',@Input) > 0 and charindex('*/',@Input, charindex('/*',@Input)) - charindex('/*',@Input) + 2 > 0
BEGIN
SET @Input = REPLACE( @Input,
substring( @Input,
charindex('/*',@Input),
charindex('*/',@Input, charindex('/*',@Input)) - charindex('/*',@Input) + 2) 
, '') 
END
set @i = @i+1
end
set @i = 1
while @i <= 5
begin
IF charindex('--',@Input) > 0 and charindex(char(13),@Input,charindex('--',@Input)) - charindex('--',@Input) +2 > 0 
BEGIN
SET @Input = 
REPLACE( @Input,
substring(@Input ,
charindex('--',@Input),
charindex(char(13),@Input,charindex('--',@Input)) - charindex('--',@Input) +2 ) 
, '') 
END
set @i = @i+1
end
SET @Output = dbo.funProcWithoutComments (@Input)
END
RETURN @Output
END
Then I find all the dependencies in the database with the following statement: 
SELECT so1.id as ID, 
so1.name As ProcName,
dbo.funProcWithoutComments(sc.text) as ProcText
into #T1
FROM sysobjects so1 
inner join syscomments sc
on so1.id = sc.id 
WHERE
so1.type = 'P' and so1.name not like 'dt_%'
-------------------------------------------------------------
select left(#T1.ProcName,30), left(T2.DependOnProc,30) from
#T1
inner join
(select id, name as DependOnProc from sysobjects where type = 'P' and name not like 'dt_%') T2
on #T1.ID <> T2.ID
WHERE #T1.ProcText LIKE '%' + T2.DependOnProc + '[' + char(9)+ char(10)+ char(13)+ char(32) + ']%'
and
CHARINDEX(#T1.ProcName, #T1.ProcText) 
<>
CHARINDEX(T2.DependOnProc, #T1.ProcText,CHARINDEX(#T1.ProcName, #T1.ProcText)+1) 
order by 1,2
--------------------------------------------------------------
drop table #T1 

Running this statement in Northwind database will yield:

ProcName             DependOnProc 

---------------------------------

proc1                    

proc2

proc2                    

proc3

proc3                    

proc4

proc4                    

proc5

In other words ProcName calls DependOnProc.

The statement excludes system procedures with prefix 'dt_'.

In addition these dependencies can be used to create a hierarchical report

useful for documentation and error handling especially when we use nested

transactions.

I will explain such examples in my next article.

Rate

5 (2)

You rated this post out of 5. Change rating

Share

Share

Rate

5 (2)

You rated this post out of 5. Change rating