我正在创建一个发送电子邮件的列表。登录的个人在数据库中有一个他们向谁报告的字段(除非出现错误或他们向任何人报告)。
因此,例如,如果我登录并单击SQL中的提交按钮,它会说我向'John Doe'报告
然后我需要抓住'John Doe'的报告并将其添加到列表中。我需要继续攀登列表,直到我们到达公司的最高层(GID将为空或无效)。
以我为例,我向'John Doe'
报告,'Tom Doe'
向usrReportsTo
报告。 Tom向他的'00000000-0000-0000-0000-000000000000'
字段中没有人报告""
。
如果usrReportsTo字段为NULL
或'00000000-0000-0000-0000-000000000000'
或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
,则循环应终止。
这是我使用的sql。
执行此循环的最干净/最好/最有效的方法是什么?在SQL或ASP.net C#中更好吗?
{{1}}
编辑#3
SQL的工作副本不会返回100%真实数据。
与cte 如 ( 从dbo.CVT_Users_usr选择usrGID,RTRIM(usrFirstName)+''+ RTRIM(usrLastName)作为名称,usrEmailAddress,usrReportsTo 联合所有 从dbo.CVT_Users_usr中选择u.usrGID,RTRIM(u.usrFirstName)+''+ RTRIM(u.usrLastName),cte.usrEmailAddress,cte.usrReportsTo 内部联接cte on u.usrReportsTo = cte.usrGID ) 从cte中选择* 其中Name ='James Wilson'
- 返回
usrGID名称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 James Wilson tom@1234.com 00000000-0000-0000-0000-000000000000
usrGID和名称是否应该与usrEmailAddress和usrReportsTo相同?我尝试将sql变为cte.USRGID和cte.Name,但它给出了最大递归错误。
有什么想法吗?
答案 0 :(得分:6)
使用common table expression
,您可以在一个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