0

私が取り組んでいる webapp には、いわゆる を保持するテーブルがありますProjectItems。問題は、さまざまな種類のプロジェクト アイテムが同じテーブルに存在することです。プロジェクト、質問、アイデア、反応を作成できます。ビットごとの列では、型が列に設定され[Type]ます。また、各プロジェクト アイテムはfk_Parent、この同じテーブルに親 ( という名前の列で定義) を持つことができます。

階層は次のとおりです。

Project(32) > Question(1) > Idea(2) > Reaction(4)

(私はDBのセットアップに影響を与えません。)

パラメーターとして渡された ID を持つアイテムのルート プロジェクト アイテム (プロジェクト タイプ) を取得するためのストアド プロシージャを作成していますが、これまでのところ、少しぎこちなく感じます。

CREATE PROC [dbo].[spProjectItemGetTopParentId]     
@ID INT

AS
    DECLARE @parentId INT
    SELECT @parentId =  fk_Parent FROM tblProjectItem WHERE ID = @ID
IF ((SELECT [Type] FROM tblProjectItem WHERE ID = @parentId) = 32)
    RETURN @parentId
ELSE
    SELECT @parentId =  fk_Parent FROM tblProjectItem WHERE ID = @parentId
IF ((SELECT [Type] FROM tblProjectItem WHERE ID = @parentId) = 32)
    RETURN @parentId
ELSE
    SELECT @parentId =  fk_Parent FROM tblProjectItem WHERE ID = @parentId
IF ((SELECT [Type] FROM tblProjectItem WHERE ID = @parentId) = 32)
    RETURN @parentId
ELSE
    SELECT @parentId =  fk_Parent FROM tblProjectItem WHERE ID = @parentId
IF ((SELECT [Type] FROM tblProjectItem WHERE ID = @parentId) = 32)
    RETURN @parentId
ELSE
RETURN 0
GO

SQLでこれを再帰的に行う方法があるかどうか疑問に思っていましたか? または、これをもう少しきれいにする他の方法はありますか?

編集:これはCTEを含むSPです:

CREATE PROC [dbo].[spTest]  
@ID INT

AS
DECLARE @parentId INT;
WITH Parents as (
    select ID,Type,fk_Parent from tblProjectItem where ID = @ID
    union all
    select pi.ID,pi.Type,pi.fk_Parent
    from
        Parents p
            inner join
        tblProjectItem pi
            on
                p.fk_Parent = pi.ID
)
select @parentId = ID from Parents where Type = 32

GO
4

2 に答える 2

1

はい、再帰 CTEはこれを見つけることができます。

;WITH Parents as (
    select ID,Type,parent_id from tblProjectItem where ID = @ID
    union all
    select pi.ID,pi.Type,pi.parent_id
    from
        Parents p
            inner join
        tblProjectItem pi
            on
                p.parent_id = pi.ID
)
select @parentId = ID from Parents where Type = 32

補足として、データベース オブジェクトの名前付けに接頭辞を使用しないことをお勧めします。ビューとテーブル (通常は区別できないようにする必要があります)を除いて、すべてのオブジェクト タイプは使用法によって明確に識別できます。その名前がストアド プロシージャ、(テーブル|ビュー)、または列などを参照しているかどうかに関係なく、特定のクエリでの名前の位置。

于 2013-11-08T15:45:54.097 に答える