sql - 如何改变递归查询的工作方式?

标签 sql sql-server

我正在尝试将存储过程剥离到核心相关列和表。我已经完成了 50%,需要帮助才能达到 100%。

这是我所拥有的,它为我提供了存储过程中的核心表对象依赖项。我还需要核心列对象依赖项。

CREATE FUNCTION GetDependents
     (@ObjectName AS SYSNAME)
RETURNS @result TABLE (Seq INT IDENTITY, 
                       ObjectName SYSNAME, 
                       Hierarchy VARCHAR(128)
                      )
AS
BEGIN
    ;WITH Obj AS 
    (
        SELECT DISTINCT
            s.id  AS ParentID,
            s.DepID AS ObjectID,
            o1.Name AS ParentName,
            o2.Name AS ChildName,
            QUOTENAME(sch1.name) + '.' + QUOTENAME(o1.Name) + '(' + RTRIM(o1.type) + ')' COLLATE SQL_Latin1_General_CP1_CI_AS AS ParentObject, 
            QUOTENAME(sch2.name) + '.' + QUOTENAME(o2.Name) + '(' + RTRIM(o2.type) + ')' COLLATE SQL_Latin1_General_CP1_CI_AS AS ObjectName
        FROM 
            sys.sysdepends s
        INNER JOIN 
            sys.all_objects o1 ON s.id = o1.object_id
        INNER JOIN 
            sys.schemas sch1 ON sch1.schema_id = o1.schema_id
        INNER JOIN 
            sys.all_objects o2 on s.DepID = o2.object_id
        INNER JOIN 
            sys.schemas sch2 ON sch2.schema_id = o2.schema_id
        WHERE 
            o1.object_id <> o2.object_id
    ), cte AS 
    (
        SELECT 
            0 AS lvl, 
            ParentID,
            ObjectId,
            ParentObject,
            ObjectName,
            CAST(ObjectID AS VARBINARY(512)) AS Sort
        FROM 
            obj 
        WHERE 
            ParentName = @ObjectName

        UNION ALL 

        SELECT
            p.lvl + 1, 
            c.ParentID, c.ObjectId, c.ParentObject, c.ObjectName,
            CAST(p.sort + CAST(c.ObjectID AS VARBINARY(16)) AS VARBINARY(512))
        FROM 
            cte p 
        INNER JOIN 
            obj c ON p.ObjectID = c.ParentID
    )
    INSERT INTO @result (ObjectName, Hierarchy)
        SELECT 
            ObjectName, '|-' + REPLICATE('-',(lvl * 4)) + ObjectName 
        FROM 
            cte
        ORDER BY 
            Sort

    RETURN 
END

CREATE PROCEDURE test1
AS
SELECT A.BusinessEntityID, 
       A.NationalIDNumber, 
       A.LoginID, 
       A.OrganizationNode, 
       A.OrganizationLevel, 
       A.JobTitle, 
       A.BirthDate, 
       A.Gender, 
       A.HireDate, 
       A.SalariedFlag, 
       A.VacationHours, 
       A.SickLeaveHours, 
       A.CurrentFlag, 
       A.rowguid, 
       A.ModifiedDate
FROM  HumanResources.Employee AS A INNER JOIN
      HumanResources.Employee AS B ON A.NationalIDNumber = B.NationalIDNumber

GO

SELECT * FROM dbo.GetDependents('test1') 

最佳答案

好了:您所需要做的就是将 col_name(s.depid, s.depnumber) AS 'column' 添加到您的 CTE:

declare @ObjectName AS SYSNAME
set @ObjectName = 'test1'

    ;WITH Obj AS (
        SELECT DISTINCT
            s.id  AS ParentID,
            s.DepID AS ObjectID,
            o1.Name AS ParentName,
            o2.Name AS ChildName,
            QUOTENAME(sch1.name) + '.' + QUOTENAME(o1.Name) 
                     + '(' + RTRIM(o1.type) + ')' 
                COLLATE SQL_Latin1_General_CP1_CI_AS 
                     AS ParentObject, 
            QUOTENAME(sch2.name) + '.' + QUOTENAME(o2.Name) 
                     + '(' + RTRIM(o2.type) + ')' 
                COLLATE SQL_Latin1_General_CP1_CI_AS AS ObjectName,
            col_name(s.depid, s.depnumber) AS 'column'
        FROM sys.sysdepends s

        INNER JOIN sys.all_objects o1 ON s.id = o1.object_id
        INNER JOIN sys.schemas sch1 ON sch1.schema_id = o1.schema_id
        INNER JOIN sys.all_objects o2 on s.DepID = o2.object_id
        INNER JOIN sys.schemas sch2 ON sch2.schema_id = o2.schema_id
              WHERE o1.object_id <> o2.object_id
    ), cte AS (
        SELECT 
            0 AS lvl, 
            ParentID,
            ObjectId,
            ParentObject,
            ObjectName,
            [column],
            CAST(ObjectID AS VARBINARY(512)) AS Sort
        FROM obj WHERE ParentName = @ObjectName
        UNION ALL 
        SELECT
            p.lvl+ 1, 
            c.ParentID,
            c.ObjectId,
            c.ParentObject,
            c.ObjectName,
            c.[column],
            CAST(p.sort + CAST(c.ObjectID AS VARBINARY(16)) 
              AS VARBINARY(512))
        FROM cte p 
        INNER JOIN obj c ON p.ObjectID = c.ParentID
    )
       SELECT 
           ObjectName,         [column],

           '|-' + REPLICATE('-',(lvl * 4)) + ObjectName 
       FROM cte
       ORDER BY Sort

结果:

|      OBJECTNAME | COLUMN |          COLUMN_2 |
|-----------------|--------|-------------------|
| [dbo].[test](U) |      t | |-[dbo].[test](U) |
| [dbo].[test](U) |     t1 | |-[dbo].[test](U) |
| [dbo].[test](U) |     t2 | |-[dbo].[test](U) |

顺便说一句,你知道 sp_depends 吗?它执行相同的操作(提示:在查询分析器中输入 sp_helptext N'sys.sp_depends')

SQL Fiddle

关于sql - 如何改变递归查询的工作方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23633762/

相关文章:

sql-server - SQL Server 2005 数据库加密 - 主 key 未保持打开状态

连接两个表的查询的 SQL Server "FOR XML"输出

mysql - 如何在mysql中定义一个100亿行的key/value表?

asp.net - 发送电子邮件,但不是现在

php - 复杂的 SQL 查询,以便检索给定时间范围内与预订系统中的房间匹配的可用床位

sql - 子查询上的 Groupwise MAX()

mysql - 如何删除 28GB 分隔文本文件中的特定行?

sql - 是否可以将可变列名传递到更新语句中?

mysql - 如何创建MySQL分层递归查询

sql - Oracle 语法左连接三个或更多表