How can i get the list of tables in the stored procedure

前端 未结 10 1767
终归单人心
终归单人心 2020-12-01 05:16

There are lot of tables and sp in the db. I find the tables name which are used in the specific sp (stored procedure).

sp_depends %sp_name% not give the

相关标签:
10条回答
  • 2020-12-01 05:52

    The two highest voted answers use a lot of deprecated tables that should be avoided.
    Here's a much cleaner way to do it.

    Get all the tables on which a stored procedure depends:

    SELECT DISTINCT p.name AS proc_name, t.name AS table_name
    FROM sys.sql_dependencies d 
    INNER JOIN sys.procedures p ON p.object_id = d.object_id
    INNER JOIN sys.tables     t ON t.object_id = d.referenced_major_id
    ORDER BY proc_name, table_name
    

    Works with MS SQL SERVER 2005+

    List of Changes:

    • sysdepends should be replaced with sys.sql_dependencies
      • The new table uses object_id instead of id
      • The new table uses referenced_major_id instead of depid
    • Using sysobjects should be replaced with more focused system catalog views
      • As marc_s pointed out, instead use sys.tables and sys.procedures
      • Note: This prevents having to check where o.xtype = 'p' (etc.)
    • Also, there is really no need for a CTE which uses ROW_NUMBER() just in order to make sure we only have one of each record set returned. That's what DISTINCT is there for!

      • In fact, SQL is smart enough to use DISTINCT behind the scenes.
      • I submit into evidence: Exhibit A. The following queries have the same Execution Plan!

        -- Complex
        WITH MyPeople AS (
          SELECT id, name,
          ROW_NUMBER() OVER(PARTITION BY id, name ORDER BY id, name) AS row
          FROM People)
        SELECT id, name
        FROM MyPeople
        WHERE row = 1
        
        -- Better
        SELECT DISTINCT id, name
        FROM People
        
    0 讨论(0)
  • 2020-12-01 05:55
    SELECT 
    NAME 
    FROM SYSOBJECTS 
    WHERE ID IN (   SELECT SD.DEPID 
                    FROM SYSOBJECTS SO, 
                    SYSDEPENDS SD
                    WHERE SO.NAME = 'SP_NAME' 
                    AND SD.ID = SO.ID
                )
    
    0 讨论(0)
  • 2020-12-01 05:57

    This code recursively looks at every Stored Procedure in your Stored Procedure and gives you the full list of all tables used.

    
    
        declare @sp_name varchar(100)
        declare @curSpName varchar(100)
        declare @curObjName varchar(255)
        declare @curXType varchar(1)
        ​
        create table #tmpTables
        (
        proc_name varchar(255),
        table_name varchar(255)
        )
        ​
        set @sp_name = 'STORED_PROCEDURE_NAME'
        ​
        ;WITH stored_procedures AS (
        SELECT 
        o.name AS proc_name, oo.name AS table_name, oo.type AS xType,
        ROW_NUMBER() OVER(partition by o.name,oo.name, oo.Type ORDER BY o.name,oo.name, oo.Type) AS row
        FROM sysdepends d 
        INNER JOIN sysobjects o ON o.id=d.id
        INNER JOIN sysobjects oo ON oo.id=d.depid
        WHERE o.xtype = 'P'
        --and oo.type = 'U' --Tables
        and o.name = @sp_name)
        SELECT proc_name, table_name, xType, 'N' Processed into ##tmpSP
        FROM stored_procedures 
        WHERE row = 1
        --ORDER BY proc_name,table_name
        ​
        ​
        While (Select count(*) from ##tmpSP where Processed = 'N')  0
        Begin
        ​
            Select top  1 @curSpName = proc_name, @curObjName = table_name, @curXType = xType
            from ##tmpSP
            where Processed = 'N'
        ​
        ​
            if @curXType = 'U'
            Begin
        ​
                insert into #tmpTables
                values (@curSpName, @curObjName)
        ​
            End
        ​
            if @curXType = 'P'
            Begin
        ​
                ;WITH stored_procedures AS (
                SELECT 
                o.name AS proc_name, oo.name AS table_name, oo.type AS xType,
                ROW_NUMBER() OVER(partition by o.name,oo.name, oo.Type ORDER BY o.name,oo.name, oo.Type) AS row
                FROM sysdepends d 
                INNER JOIN sysobjects o ON o.id=d.id
                INNER JOIN sysobjects oo ON oo.id=d.depid
                WHERE o.xtype = 'P'
                and oo.type = 'U' --Tables
                and o.name = @curObjName)
                insert into #tmpTables
                SELECT @curSpName, table_name 
                FROM stored_procedures 
                WHERE row = 1
                ORDER BY proc_name,table_name
        ​
                ;WITH stored_procedures AS (
                SELECT 
                o.name AS proc_name, oo.name AS table_name, oo.type AS xType,
                ROW_NUMBER() OVER(partition by o.name,oo.name, oo.Type ORDER BY o.name,oo.name, oo.Type) AS row
                FROM sysdepends d 
                INNER JOIN sysobjects o ON o.id=d.id
                INNER JOIN sysobjects oo ON oo.id=d.depid
                WHERE o.xtype = 'P'
                and oo.type = 'P' --SP's
                and o.name = @curObjName)
                insert into ##tmpSP
                SELECT proc_name, table_name, xType, 'N'  
                FROM stored_procedures 
                WHERE row = 1
                and proc_name not in 
                (
                    Select proc_name
                    from ##tmpSP
                )
                ORDER BY proc_name,table_name
        ​
            End
        ​
            if @curXType = 'v'
            Begin
        ​
                ;WITH stored_procedures AS (
                SELECT 
                o.name AS proc_name, oo.name AS table_name, oo.type AS xType,
                ROW_NUMBER() OVER(partition by o.name,oo.name, oo.Type ORDER BY o.name,oo.name, oo.Type) AS row
                FROM sysdepends d 
                INNER JOIN sysobjects o ON o.id=d.id
                INNER JOIN sysobjects oo ON oo.id=d.depid
                WHERE o.xtype = 'v'
                and oo.type = 'U' --Tables
                and o.name = @curObjName)
                insert into #tmpTables
                SELECT proc_name, table_name 
                FROM stored_procedures 
                WHERE row = 1
                ORDER BY proc_name,table_name
        ​
            End
        ​
            update ##tmpSP
            set Processed = 'Y'
            where table_name = @curObjName
        ​
        ​
        End
        ​
        ​
        Select distinct table_name
        from #tmpTables
        ​
        drop table #tmpTables
        drop table ##tmpSP
    
    
    0 讨论(0)
  • 2020-12-01 06:00

    But please note that the sysdepends will not give the table names if they are used in dynamic sql. What I suggest is to search reversely ie: create a loop search the tables in the syscomments. The below stored procedure may help

    CREATE PROCEDURE dbo.sp_getObjects
    (
        @ObjName VARCHAR(255)
    )
    AS
    BEGIN
        SET NOCOUNT ON
        DECLARE @Idkeyst INTEGER
        DECLARE @Idkeyed INTEGER
        DECLARE @tblName VARCHAR(255)
        DECLARE @Objects VARCHAR(MAX)
        IF NOT EXISTS(SELECT 1 FROM sys.objects where NAME = @ObjName AND type in ('P', 'FN','TR'))
        BEGIN
            PRINT 'NO Text Available for the Parameter'
            RETURN(0)
        END
        CREATE TABLE #ProcStr
        (
            Idkey       INT IDENTITY(1,1),
            ScriptStr   VARCHAR(MAX)
        )
        CREATE TABLE #Depends
        (
            Idkey           INT IDENTITY(1,1),
            Depends         VARCHAR(255)
        )
        CREATE TABLE #Objects
        (
            Idkey           INT IDENTITY(1,1),
            ObjectName      VARCHAR(255)
        )
        INSERT INTO #ProcStr
        (ScriptStr)
        EXEC sp_helptext @ObjName
        DELETE #ProcStr WHERE LTRIM(ScriptStr) LIKE '--%'
        DELETE #ProcStr WHERE LTRIM(REPLACE(ScriptStr,CHAR(9),'')) LIKE '--%'
    
        SET @Idkeyst = 0
        SET @Idkeyed = 0
        WHILE 1=1
        BEGIN
            SELECT @Idkeyst = MIN(idKey) FROM #ProcStr WHERE ScriptStr like '%/*%' and Idkey > @Idkeyst
            IF @Idkeyst IS NULL
                BREAK
            SELECT @Idkeyed = MIN(idKey) FROM #ProcStr WHERE ScriptStr like '%*/%' and Idkey >= @Idkeyst
            DELETE #ProcStr WHERE Idkey >= @Idkeyst and Idkey <=@Idkeyed
        END
        DELETE #ProcStr WHERE ISNULL(LTRIM(REPLACE(ScriptStr,CHAR(9),'')),'')=''    
        INSERT INTO #Depends
        (Depends)
        SELECT DISTINCT t.name 
        FROM sys.sql_dependencies d 
        INNER JOIN sys.procedures p ON p.object_id = d.object_id
        INNER JOIN sys.tables     t ON t.object_id = d.referenced_major_id
        where p.name = @ObjName
    
        INSERT INTO #Objects
        SELECT name from sys.objects o WHERE Type = 'U' AND NOT EXISTS
        (SELECT 1 FROM #Depends WHERE Depends = o.name)
    
        SET @Objects = ''
        SELECT @Objects = CASE WHEN ISNULL(@Objects,'') = '' THEN '' ELSE @Objects+', ' END+ Depends
        FROM #Depends
    
        UPDATE #ProcStr
        SET ScriptStr = LTRIM(RTRIM(ScriptStr))
        UPDATE #ProcStr
        SET ScriptStr = REPLACE(ScriptStr,CHAR(9),'')
        UPDATE #ProcStr
        SET ScriptStr = REPLACE(ScriptStr,CHAR(13),'')
        UPDATE #ProcStr
        SET ScriptStr = REPLACE(ScriptStr,CHAR(10),'')
        SET @tblName = ''
        SET @Idkeyst = 0
        WHILE 1=1
        BEGIN
            SELECT @Idkeyst = MIN(idKey) FROM #Objects WHERE Idkey > @Idkeyst
            IF @Idkeyst IS NULL
                BREAK
            SELECT @tblName = ObjectName FROM #Objects WHERE Idkey = @Idkeyst
            IF Exists (SELECT 1 FROM #ProcStr WHERE (ScriptStr LIKE '% '+@tblName+' %' 
                            OR ScriptStr LIKE '%.'+@tblName+' %' OR ScriptStr LIKE @tblName+' %' OR ScriptStr LIKE @tblName
                            --OR ScriptStr LIKE '%'+@tblName 
                            OR ScriptStr LIKE '% '+@tblName+'''%' OR ScriptStr LIKE @tblName+'''%'))
            BEGIN
                SET @Objects = CASE WHEN ISNULL(@Objects,'')<>'' THEN @Objects+', '+@tblName ELSE @tblName END
            END
        END
    
        IF ISNULL(@Objects,'') = ''
        BEGIN
            PRINT 'NO Tables are reffered in the stored procedures'
            RETURN(0)
        END
        PRINT @Objects
        SET NOCOUNT OFF
    END
    
    0 讨论(0)
  • 2020-12-01 06:02

    Here is an example to find list of tables used in a procedure

    ;WITH procs
    AS
    (
    SELECT o1.name AS proc_name,
    o2.name AS table_name,
    ROW_NUMBER() OVER(PARTITION BY o1.name,o2.name ORDER BY o1.name,o2.name) AS row
    FROM sysdepends d
    INNER JOIN sysobjects o1
    ON o1.id=d.id
    INNER JOIN sysobjects o2
    ON o2.id=d.depid
    WHERE o1.xtype = 'P'
    --AND o2.name = 'tabname1' OR o2.name = 'tblname2'
    )
    SELECT proc_name, table_name
    FROM procs
    WHERE row = 1
    ORDER BY proc_name, table_name
    

    Also, this query returns all the table names of all dependent tables in a Stored procedure.

    SELECT DISTINCT o.id, o.name as 'Procedure_Name' , oo.name as 'Table_Name'
    FROM sysdepends d, sysobjects o, sysobjects oo
    WHERE o.id=d.id 
    and oo.id=d.depid and depnumber=1
    ORDER BY o.name,oo.name
    
    0 讨论(0)
  • 2020-12-01 06:07

    KyleMit's answer is using a table that will be deprecated soon as well. It is recommended to use sys.sql_experssion_dependencies instead of sys.sql_dependencies, e.g.,

    SELECT DISTINCT p.name AS proc_name, t.name AS table_name
    FROM sys.sql_expression_dependencies d
    INNER JOIN sys.procedures p ON p.object_id = d.referencing_id
    INNER JOIN sys.tables t     ON t.object_id = d.referenced_id
    ORDER BY proc_name, table_name
    

    This should work with SQL Server 2008+.

    I did not have a high enough reputation to comment directly on the referenced answer.

    0 讨论(0)
提交回复
热议问题