为父表中的每一行插入子表

时间:2012-01-02 14:24:43

标签: sql sql-server cursor

我的数据库看起来像这样

tblAudits
PK AuditID
AuditStatus nvarchar(50)

tblQuestionDefs
PK QuestionID

tblAuditAnswers
PK AnswerID
FK AuditID
FK QuestionID

我最近在审核中添加了一些新问题,我想为每个新问题添加一个答案记录到所有活动审核中。在SQL中执行此操作的最佳方法是什么?我知道我可以使用游标循环,但这些都是非常慢的AFAIK。有没有基于集合的方式呢?

这是基于游标的代码

declare
    @AuditID int

declare AuditsCursor cursor fast_forward for
    select AuditID from tblAudits where AuditStatus='Issued' or AuditStatus='Pending' order by AuditID desc

open AuditsCursor
fetch next from AuditsCursor
into @AuditID

while @@FETCH_STATUS = 0
begin

    insert into tblAuditAnswers (AuditID, QuestionID)
    select @AuditID as AuditID, QuestionID
    from tblQuestionDefs
    where QuestionID not in (
        select QuestionID from tblAuditAnswers where AuditID=@AuditID
    )

fetch next from AuditsCursor
into @AuditID
end

close AuditsCursor
deallocate AuditsCursor

3 个答案:

答案 0 :(得分:3)

insert into tblAuditAnswers (AuditID, QuestionID)
select A.AuditID, QD.QuestionID
from tblAudits as A
  cross join tblQuestionDefs as QD
where (A.AuditStatus='Issued' or A.AuditStatus='Pending') and
        not exists (select *
                    from tblAuditAnswers as AA
                    where QD.QuestionID = AA.QuestionID and
                          A.AuditID = AA.AuditID)

http://data.stackexchange.com/stackoverflow/q/123061/

答案 1 :(得分:2)

INSERT INTO tblAuditAnswers
            (AuditID,
             QuestionID)
SELECT A.AuditID,
       Q.QuestionID
FROM   tblAudits A
       CROSS JOIN (SELECT QuestionID
                   FROM   tblQuestionDefs
                   EXCEPT
                   SELECT QuestionID
                   FROM   tblAuditAnswers) Q
WHERE  A.AuditStatus IN ( 'Issued', 'Pending' ) 

答案 2 :(得分:0)

不需要游标。

INSERT INTO tblAuditAnswers
    (AuditID, QuestionID)
SELECT
    A.AuditID, Q.QuestionID
FROM
    tblAudits A
    CROSS JOIN tblQuestionDefs Q
    LEFT JOIN tblAuditAnswers AA
        ON A.AuditID = AA.AuditID AND Q.QuestionID = AA.QuestionID
WHERE
    A.AuditStatus='Issued' OR A.AuditStatus='Pending' AND
    AA.AuditID IS NULL
ORDER BY
    A.AuditID DESC

如果问题定义与特定审计类型相关,那么您还应该通过内部联接替换CROSS JOIN:

INNER JOIN tblQuestionDefs Q
    A.AuditTypeID = Q.AuditTypeID