3

メールを送信するリストを作成しています。ログインしている個人は、データベース内に報告先のフィールドを持っています (エラーがあるか、誰にも報告しない場合を除きます)。

たとえば、ログインして SQL の送信ボタンをクリックすると、'John Doe' に報告すると表示されます。

次に、'John Doe' の報告先を取得し、それをリストに追加する必要があります。会社のトップに到達するまでリストを登り続ける必要があります (GID は空白または null になります)。

私を例にとると、私は に'John Doe'報告し'Tom Doe'ます。トムは自分のusrReportsTo畑がこんな感じだと誰にも報告しない'00000000-0000-0000-0000-000000000000'.

usrReportsTo フィールドが""orのNULL場合'00000000-0000-0000-0000-000000000000'、ループは終了します。

これが私が使用したSQLです。

このループを実行するための最もクリーン/最新/最も効率的な方法は何ですか?SQLまたはASP.net C#で実行する方が良いですか?

select usrReportsTo from dbo.CVT_Users_usr, usrEmailAddress
WHERE RTRIM(usrFirstName) + ' ' + RTRIM(usrLastName) = 'James Wilson' 
-- Returns 'James Wilson' + email

SELECT RTRIM(usrFirstName) + ' ' + RTRIM(usrLastName) as Name, usrEmailAddress, usrReportsTo from dbo.CVT_Users_usr
WHERE usrGID = '38922F83-4B6E-499E-BF4F-EF0B094F47F7'
-- Returns 'John Doe' + email + reportsTo

SELECT RTRIM(usrFirstName) + ' ' + RTRIM(usrLastName) as Name, usrEmailAddress, usrReportsTo from dbo.CVT_Users_usr
WHERE usrGID = 'FB8F4939-3956-4834-9D89-D72AFB8BF3E0'
-- Returns 'Tom Doe' + email + reportsTo

編集 #3

SQL の作業コピーは、100% 真のデータを返しません。

cte AS ( usrGID、RTRIM(usrFirstName) + ' ' + RTRIM(usrLastName) を Name として選択し、dbo.CVT_Users_usr から usrEmailAddress、usrReportsTo を選択します。ユニオンはすべて u.usrGID、RTRIM(u.usrFirstName) + ' ' + RTRIM(u. usrLastName), cte.usrEmailAddress, cte.usrReportsTo from dbo.CVT_Users_usr u.usrReportsTo = cte.usrGID で cte を内部結合) select * from cte where Name = 'James Wilson'

- 戻り値

usrGID Name usrEmailAddress usrReportsTo E1DAFC11-BE35-4730-9961-68EEF8D85DE4 James Wilson 38922F83-4B6E-499E-BF4F-EF0B094F47F7 E1DAFC11-BE35-4730-9961-68EEF8D85DE4 James Wilson john@1234.com FB8F4939-3956-4834-9D89-D72AFB8BF3E0 E1DAFC11 -BE35-4730-9961-68EEF8D85DE4 ジェームズ・ウィルソン tom@1234.com 00000000-0000-0000-0000-000000000000

usrGID と名前は、usrEmailAddress と usrReportsTo と同じように一致すべきではありませんか? SQLをcte.USRGIDおよびcte.Nameに変更しようとしましたが、最大再帰エラーが発生しました。

何か案は?

4

1 に答える 1

6

を使用するcommon table expressionと、(再帰結合を介して) 1 つの SQL ステートメントで完全な結果セットを生成できるため、ループをまったく回避できます。

キー フィールドを使用した基本的な例

create table #CVT_Users_usr (usrGid uniqueidentifier, usrEmailAddress varchar(50), usrFirstName varchar(20), usrLastName varchar(20), usrReportsTo uniqueidentifier)

insert #CVT_Users_usr values    
('38922F83-4B6E-499E-BF4F-EF0B094F47F7' , 'james@wilson.com','james','wilson', 'E1DAFC11-BE35-4730-9961-68EEF8D85DE4'),
('E1DAFC11-BE35-4730-9961-68EEF8D85DE4', 'john@doe.com','john','doe', 'FB8F4939-3956-4834-9D89-D72AFB8BF3E0'),
('FB8F4939-3956-4834-9D89-D72AFB8BF3E0', 'tom@doe.com','tom','doe' ,'00000000-0000-0000-0000-000000000000'),
('FE6899A5-63BA-42B7-A70E-011711A5FAC6', 'ken@ken.com','ken', 'kenneths', 'FB8F4939-3956-4834-9D89-D72AFB8BF3E0')

declare @id uniqueidentifier
select @id = usrGid from #CVT_Users_usr where usrFirstName='james' and usrLastName='wilson'

;with cte as
(
select usrGid, usrEmailAddress, usrFirstName, usrLastName, usrReportsTo from #CVT_Users_usr
union all
select u.usrGid,  cte.usrEmailAddress, cte.usrFirstName, cte.usrLastName, cte.usrReportsTo 
from #CVT_Users_usr u
    inner join cte on u.usrReportsTo= cte.usrGid
)
    select usrFirstName + ' ' + usrLastName, usrEmailAddress  from cte
    where usrGid=@id

drop table #CVT_Users_usr
于 2012-08-20T21:33:10.153 に答える