0

昨天我注意到一件非常有趣(也是出乎意料)的事情。我被赋予了一项任务(在生产环境中),通过获取 dummytable 中存在的所有值来更新 TableA 的三列(由于一些明显的原因,我正在更改表和列名)。两个表的主键都是 A 列。我知道这个任务非常简单,可以通过多种方式完成,但我选择为此编写一个存储过程(如下所示)。

当存储过程执行完毕后,我们注意到 B、C 和 statusCode 列具有相同的值(即数千条记录在这三列中具有相同的值)。有人可以告诉我出了什么问题吗?

1)这个存储过程有什么问题(或缺失)?(虚拟表也有数千条记录) 2)除了创建存储过程之外,执行此任务的最佳方法是什么?

PS:我使用 MySQL 工作台在生产环境中创建(也执行了)这个存储过程,并且在执行过程中出现异常,指出“与 MySQL 服务器的连接丢失”,但我猜是因为我在远程机器然后在执行过程时服务器上没有中断。

这是我的存储过程。

DELIMITER $$

CREATE DEFINER=`ABC`@`%` PROCEDURE `RetrieveExtractionData`()

BEGIN

DECLARE claimlisttraversed BOOLEAN DEFAULT FALSE;

DECLARE a VARCHAR(20);

DECLARE b INTEGER;

DECLARE c INTEGER;


DECLARE claimlist CURSOR FOR SELECT
`dummytable`.`A`,
`dummytable`.`B`,
`dummytable`.`C`
FROM `ABC`.`dummytable`;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET claimlisttraversed = TRUE;


OPEN claimlist;

claimlistloop: LOOP

    FETCH claimlist INTO a, b, c;

    IF claimlisttraversed THEN
        CLOSE claimlist;
        LEAVE claimlistloop;
    END IF;
    UPDATE `ABC`.`TableA`
SET
`B` = b,
`C` = c,
`statuscode` = 'Sent'
WHERE `A` = a;

END LOOP claimlistloop;

END
4

3 回答 3

1

对于你的第一个问题:

1)这个存储过程有什么问题(或缺失)?(虚拟表也有数千条记录)

我猜你忘记CLOSECURSOR。在你结束之后,LOOP你应该。CLOSECURSOR

END LOOP claimlistloop;

CLOSE claimlist;

END

2)除了创建存储过程之外,执行此任务的最佳方法是什么?

这样做STORED PROCEDURE应该没问题。而且使用CURSOR也很好,因为您只需执行一次该过程(我猜是因为这是一个生产修复程序)。

但是根据您的问题,您只想TableA根据提供的DummyTable. 我假设这些表具有相同的列。

所以我认为这个查询比CURSOR

UPDATE TableA A
    INNER JOIN DummyTable D ON D.A = A.A
    SET A.B = D.B
        , A.C = D.C
        , A.statuscode = 'Sent';

但请先在备用或虚拟桌子上尝试。我还没有测试过。

于 2013-06-26T08:06:37.827 回答
1

忘记光标。事实上,如果可以避免的话,你永远不应该使用游标。光标非常慢。

简单地做

UPDATE 
yourTable yt
INNER JOIN dummyTable dt ON yt.A = dt.A
SET
yt.B = dt.B,
yt.C = dt.C;

你很好。

于 2013-06-26T08:12:16.330 回答
1

1)这个存储过程有什么问题(或缺失)?(虚拟表也有数千条记录)
2)除了创建存储过程之外,执行此任务的最佳方法是什么?

恕我直言,您目前缺少的最重要的事情是您不需要任何游标。您的整个存储过程是一个UPDATE语句。单独执行或包装在存储过程中

CREATE PROCEDURE RetrieveExtractionData()
UPDATE TableA a JOIN dummytable d
    ON a.a = d.a
   SET a.b = d.b, a.c = d.c, a.statuscode = 'Sent'; 

您甚至不需要更改分隔符并使用BEGIN ... END

这是SQLFiddle演示。

于 2013-06-26T08:12:25.807 回答