0

昨日、非常に興味深い(そして予想外の)ことに気づきました。ダミーテーブルに存在するすべての値を取得することにより、TableA の 3 つの列を更新するタスク (実稼働環境で) を与えられました (いくつかの明らかな理由により、テーブルと列の名前を変更しています)。両方のテーブルの主キーは列 A です。このタスクは非常に単純で、いくつかの方法で実行できることはわかっていますが、そのためのストアド プロシージャ (以下に示す) を作成することにしました。

ストアド プロシージャの実行が終了すると、列 B、C、および statusCode が同じ値を持っていることに気付きました (つまり、何千ものレコードがこれら 3 つの列で同じ値を持っていました)。誰かが何がうまくいかなかったのか教えてもらえますか?

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) このストアド プロシージャのどこが間違っていますか (または不足していますか)。(ダミーテーブルにも数千のレコードがありました)

を忘れてしまったようCLOSEですCURSORLOOPを終了した直後にCLOSECURSOR.

END LOOP claimlistloop;

CLOSE claimlist;

END

2) ストアド プロシージャを作成する以外に、このタスクを実行する最善の方法は何ですか?

でそれを行うことはSTORED PROCEDURE問題ないはずです。またCURSOR、プロシージャを 1 回実行するだけなので、使用しても問題ありません (これは製品の修正であるためだと思います)。

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) ストアド プロシージャを作成する以外に、このタスクを実行する最善の方法は何ですか?

私が現在見逃している最も重要なことは、そのためにカーソルが必要ないということです。ストアド プロシージャ全体が 1 つの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 に答える