我有四个名为Task,ProjectTeamMemeber,Hierarchy和Assignment的表 每个任务都通过Heirarchy与项目相关,每个项目都有团队成员,可以通过ProjectTeamMember查看。
select
TH.TaskId As TaskID, P.PersonId As PersonID
from
Task T
Inner join Hierarchy TH on T.Id = TH.TaskId
Inner join ProjectTeamMemeber PTM on TH.ProjectId = P.TaskId
where
T.name = 'work'
上述查询返回分配给任务名称为“work”
的特定项目的所有人员TaskId PersonId
1347 50
1350 50
3377 50
3403 598
3411 1450
3411 1454
3411 1472
我有另一张表格Assigment,我可以从中看到分配给特定任务的人员的身份。
select
T.Id, A.PersonId
from
Task T
inner join Assignment A ON T.Id = A.TaskId
where
T.name = 'work'
上述查询返回分配给任务的所有人员,称为“工作”。
TaskId PersonId
1347 50
1350 50
3411 1472
现在,我必须在这里实现的是将所有人分配到名为“work”的任务,这些任务分配给任务名称为“work”的项目。简单地说,我必须写一些sql语句,之后我的第二个查询写出与第一个查询相同的结果。
到目前为止,我已尝试用cusrsors做到这一点,但它不起作用。以下是
的代码DECLARE @TaskId int
DECLARE @PersonId int
DECLARE @Id int
DECLARE db_cursor CURSOR FOR
select
TH.TaskId As TaskID, P.PersonId As PersonID
from
Task T
Inner join Hierarchy TH on T.Id = TH.TaskId
Inner join ProjectTeamMemeber PTM on TH.ProjectId = P.TaskId
where
T.name = 'work'
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @TaskId, @PersonId
BEGIN
If not exists ( select 1 from Assignment where TaskId=@TaskId and PersonId=@PersonId)
BEGIN
EXEC GetUniqueIdentifier @Id OUTPUT;
Insert INTO Assignment (Id, TaskId, PersonId) values (@Id, @TaskId, @PersonId)
END
END
CLOSE db_cursor
DEALLOCATE db_cursor
(注意:我必须使用语句EXEC GetUniqueIdentifier @Id OUTPUT;来生成Id。我知道可能有不同且更可靠的方法来生成ID但由于某些限制我无法更改如何生成Id。)
编辑:
根据 LAMAK 回答我跑了
DECLARE @ids int
INSERT INTO Assignment (Id, TaskId, PersonId)
EXEC GetUniqueIdentifier @ids OUTPUT;
SELECT
@ids,
TH.TaskId As TaskID,
P.PersonId As PersonID,
FROM
Task T
INNER JOIN Hierarchy TH on T.Id = TH.TaskId
INNER JOIN ProjectTeamMember P on TH.ProjectId = P.TaskId
WHERE
T.name = 'Customer work'
AND NOT EXISTS( SELECT 1 FROM Assignment
WHERE TaskID = TH.TaskId
AND PersonId = P.PersonId)
答案 0 :(得分:2)
您不需要CURSOR
,您可以使用基于集合的解决方案:
INSERT INTO Assignment (Id, TaskId, PersonId)
SELECT
NEWID(),
TH.TaskId As TaskID,
P.PersonId As PersonID
FROM
Task T
INNER JOIN Hierarchy TH on T.Id = TH.TaskId
INNER JOIN ProjectTeamMemeber PTM on TH.ProjectId = P.TaskId
WHERE
T.name = 'work'
AND NOT EXISTS( SELECT 1 FROM Assignment
WHERE TaskID = T.TaskId
AND PersonId = P.PersonId)
关于NEWID()
,你真的需要检查碰撞吗?我认为可以安全地假设NEWID()
在同一台机器上运行时是唯一的。即使在不同的服务器上,重复值的可能性也非常小。
<强>已更新强>
好的,所以,您不需要UNIQUEIDENTIFIER
而 要使用GetUniqueIdentifier
sp(名称也很严重,因为UNIQUEIDENTIFIER
是一个数据类型,可能带来混乱)。然后我担心你需要使用CURSOR
。在大多数情况下,您的光标似乎很好,唯一可见的变化是您没有获取光标的下一个值:
DECLARE @TaskId int
DECLARE @PersonId int
DECLARE @Id int
DECLARE db_cursor CURSOR FOR
select
TH.TaskId As TaskID, P.PersonId As PersonID
from
Task T
Inner join Hierarchy TH on T.Id = TH.TaskId
Inner join ProjectTeamMemeber PTM on TH.ProjectId = P.TaskId
where
T.name = 'work'
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @TaskId, @PersonId
BEGIN
If not exists (select 1 from Assignment where TaskId=@TaskId and PersonId=@PersonId)
BEGIN
EXEC GetUniqueIdentifier @Id OUTPUT;
Insert INTO Assignment (Id, TaskId, PersonId)
values (@Id, @TaskId, @PersonId)
END
FETCH NEXT FROM db_cursor INTO @TaskId, @PersonId
END
CLOSE db_cursor
DEALLOCATE db_cursor