光标陷入无限循环

发布于 2024-11-26 21:46:38 字数 1626 浏览 1 评论 0原文

第一次尝试使用光标,所以放轻松 =P 光标应该抓取全部位于伞组下的公司 ID 列表。然后定位特定公司,将其工作流程记录复制到光标中的公司。

它无限地将这些工作流程记录插入到所有公司中......这里有什么问题?

n00b错误在哪里?

DECLARE @GroupId int = 36;
DECLARE @CompanyToCopy int = 190
DECLARE @NextId int;
Declare @Companies CURSOR;

SET @Companies = CURSOR FOR 
SELECT CompanyId
FROM Company C 
    INNER JOIN [Group] G 
        ON C.GroupID = G.GroupID
WHERE   C.CompanyID != 190 
        AND
        G.GroupId = @GroupId
        AND
        C.CompanyID != 0

OPEN @Companies
FETCH NEXT
FROM @Companies INTO @NextId

WHILE (@@FETCH_STATUS = 0)
BEGIN

    INSERT INTO COI.Workflow(CompanyID, EndOfWorkflowAction, LetterType, Name)
    (SELECT 
            @NextId,
            W.EndOfWorkflowAction,
            W.LetterType,
            W.Name
     FROM COI.Workflow W)

    FETCH NEXT
    FROM @Companies INTO @NextId
END
CLOSE @Companies;
DEALLOCATE @Companies;

编辑:

我决定尝试将这个集合作为基础,只是因为在被告知这样做之后......我意识到我并没有真正找到关于如何将其作为基于集合的查询的答案。

感谢大家的帮助。我将发布基于集合的版本供后代使用。

INSERT INTO COI.Workflow(CompanyID, EndOfWorkflowAction, LetterType, Name)
(
SELECT 
    CG.CompanyId,
    W.EndOfWorkflowAction,
    W.LetterType,
    W.Name
FROM COI.Workflow W
     CROSS JOIN (SELECT C.CompanyID
                 FROM Company C 
                    INNER JOIN [Group] G
                        ON G.GroupID = C.GroupID
                 WHERE  C.CompanyID != 190 
                        AND 
                        C.CompanyID != 0
                        AND 
                        G.GroupID = 36
                 ) AS CG
 WHERE W.CompanyID = 190
 )

First attempt at a cursor so take it easy =P The cursor is supposed to grab a list of company ids that are all under a umbrella group. Then target a specific company and copy its workflow records to the companies in the cursor.

It infinitely inserts these workflow records into all the companies ... what is the issue here?

Where is the n00b mistake?

DECLARE @GroupId int = 36;
DECLARE @CompanyToCopy int = 190
DECLARE @NextId int;
Declare @Companies CURSOR;

SET @Companies = CURSOR FOR 
SELECT CompanyId
FROM Company C 
    INNER JOIN [Group] G 
        ON C.GroupID = G.GroupID
WHERE   C.CompanyID != 190 
        AND
        G.GroupId = @GroupId
        AND
        C.CompanyID != 0

OPEN @Companies
FETCH NEXT
FROM @Companies INTO @NextId

WHILE (@@FETCH_STATUS = 0)
BEGIN

    INSERT INTO COI.Workflow(CompanyID, EndOfWorkflowAction, LetterType, Name)
    (SELECT 
            @NextId,
            W.EndOfWorkflowAction,
            W.LetterType,
            W.Name
     FROM COI.Workflow W)

    FETCH NEXT
    FROM @Companies INTO @NextId
END
CLOSE @Companies;
DEALLOCATE @Companies;

Edit:

I decided to attempt making this set based just because after being told to do it ... I realized I didn't really quite have the answer as to how to do it as a set based query.

Thanks for all the help everyone. I'll post the set based version for posterity.

INSERT INTO COI.Workflow(CompanyID, EndOfWorkflowAction, LetterType, Name)
(
SELECT 
    CG.CompanyId,
    W.EndOfWorkflowAction,
    W.LetterType,
    W.Name
FROM COI.Workflow W
     CROSS JOIN (SELECT C.CompanyID
                 FROM Company C 
                    INNER JOIN [Group] G
                        ON G.GroupID = C.GroupID
                 WHERE  C.CompanyID != 190 
                        AND 
                        C.CompanyID != 0
                        AND 
                        G.GroupID = 36
                 ) AS CG
 WHERE W.CompanyID = 190
 )

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

柒七 2024-12-03 21:46:38

你对此没有 WHERE 条件:

SELECT 
            @NextId,
            W.EndOfWorkflowAction,
            W.LetterType,
            W.Name
     FROM COI.Workflow W
     -- WHERE CompanyID = @CompanyToCopy -- This should be here

所以你得到了一种加倍效果。

initial state, company 190, seed row (0)

pass one, company 2, copy of seed row (1)
now 2 rows

pass two, company 3, copy of seed row (0) - call this (2)
pass two, company 3, copy of copy of seed row (1) - call this (3)
now 4 rows

then 8 rows, etc

You have no WHERE condition on this:

SELECT 
            @NextId,
            W.EndOfWorkflowAction,
            W.LetterType,
            W.Name
     FROM COI.Workflow W
     -- WHERE CompanyID = @CompanyToCopy -- This should be here

So you are getting a kind of doubling effect.

initial state, company 190, seed row (0)

pass one, company 2, copy of seed row (1)
now 2 rows

pass two, company 3, copy of seed row (0) - call this (2)
pass two, company 3, copy of copy of seed row (1) - call this (3)
now 4 rows

then 8 rows, etc
输什么也不输骨气 2024-12-03 21:46:38

您将在每次迭代的工作流表中插入所有工作流记录的新副本,因此每次大小都会增加一倍。例如,如果您的光标中有 30 个项目,您最终会得到一个工作流程表,其中的记录数量比以前多 1073741824 倍。

You are inserting a new copy of all workflow records in the workflow table for each iteration, so it will double in size each time. If you for example have 30 items in your cursor, you will end up with a workflow table with 1073741824 times more records than it had before.

灵芸 2024-12-03 21:46:38

我相信你的逻辑是错误的(由于使用了光标,它有些隐藏!)。

您发布的代码正在尝试将一行插入到 COI.Workflow 中,其中 COI.Workflow 中的每一行乘以与您第一个选择的条件匹配的公司数量。 (请注意插入的 SELECT 语句没有条件:您正在选择整个表)。每次循环时,COI.Workflow 中的行数都会加倍,

因此,它不是无限的,但很可能非常非常长!

我建议你重写为基于集合的语句,逻辑会变得更清晰。

I beieve your logic is wrong (it's somewhat hidden because of the use of a cursor!).

Your posted code is attempting to insert a row into into COI.Workflow for every row in COI.Workflow times the number of companies matching your first select's conditions. (Notice how your insert's SELECT statement has no condition: you are selecting the whole table). On each time through the loop, you are doubling the number of rows in COI.Workflow

So, it's not infinite but it could well be very, very long!

I suggest you rewrite as a set based statement and the logic will become clearer.

ぃ弥猫深巷。 2024-12-03 21:46:38

第一次使用游标是可以的,所有问题都在INSERT ... SELECT逻辑中。
我无法理解您需要将什么插入到 COI.Workflow 表中。
我同意之前的评论员的观点,即您当前的 WHERE 条件将记录加倍,但我无法相信您每次都想为每个公司插入全倍记录。
所以,我认为您需要类似的东西

INSERT INTO COI.Workflow(CompanyID, EndOfWorkflowAction, LetterType, Name)
(SELECT TOP 1
        @NextId,
        W.EndOfWorkflowAction,
        W.LetterType,
        W.Name
 FROM COI.Workflow W)

,或者,我们需要更多地了解您插入记录的逻辑。

First use of cursor is OK, all problems in INSERT ... SELECT logic.
I cannot understand what do you need to insert into COI.Workflow table.
I agree with previous commentatorts that your current WHERE condition doubles records, but I cannot believe that you want to insert the full-doubled records for each company each time.
so, I think you need something like

INSERT INTO COI.Workflow(CompanyID, EndOfWorkflowAction, LetterType, Name)
(SELECT TOP 1
        @NextId,
        W.EndOfWorkflowAction,
        W.LetterType,
        W.Name
 FROM COI.Workflow W)

Or, we need to know more about your logic of inserting the records.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文