1

これは私の最初のStackOverflow投稿です!コミュニティは大きな助けになりました!

次のようなCSVを使用した一時テーブルを介して、テーブルに挿入しようとしている90K行のCSVがあります。

CREATE TEMPORARY TABLE temp_product like product;
LOAD DATA LOCAL INFILE "myfile.csv"
...

しかし、トランザクションを含むプロシージャを介して挿入といくつかの追加操作をまとめようとしています。何かが失敗した場合、または警告がスローされた場合に備えて、終了ハンドラがあります。

CREATE PROCEDURE update_products ()
BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION, NOT FOUND, SQLWARNING ROLLBACK;
    START TRANSACTION;
    ....

エラーが発生した場合に自動的にロールバックでき、トランザクションの論理チャンク全体を適切にラップできるため、このアプローチが気に入っています。悲しいかな:

Error : LOAD DATA is not allowed in stored procedures

(これがなぜであるかはわかりませんか?まだサポートされていないだけだと思いますか?)構文が正しいかどうかはわかりませんが(またはこれが可能かどうか)、次のようなものでも問題ありません。

DECLARE EXIT HANDLER FOR SQLEXCEPTION, NOT FOUND, SQLWARNING ROLLBACK;
START TRANSACTION;

しかし、それは明らかな構文エラーをスローします:

Error : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DECLARE EXIT HANDLER FOR SQLEXCEPTION, NOT FOUND, SQLWARNING ROLLBACK' at line 1

別の方法でCSVを読み込むことができれば、この作業を行うことができるようですが、挿入を一括で行う速度が低下したり、ディスクベースのテーブルを使用する必要がある可能性があります。それに複数の接続を行います。私が理解している限り、一時テーブルは単一の接続/トランザクションに対してのみ存在し、MySQLクライアントであるnavicatがこれをどのように管理するかは100%確実ではありません。

とのトランザクションでエラー/警告が発生したときに自動的にロールバックするスクリプトを管理する最も適切な方法である場合は、これをすべてPHPでラップすることにも反対しませんLOAD DATA

私もこれに完全に間違って近づいていると私に言ってください。私がしていることを行うには、おそらくもっと賢い方法があるように感じます。

4

1 に答える 1

2

残念ながらLOAD DATA INFILE、ストアドプロシージャはサポートされていません。誰かがMySQLストアドプロシージャを使用してシェルスクリプトを呼び出して実際にアップロードを実行するという回避策のハックを見たことがあることを思い出しますが、これはセキュリティ面で潜在的に問題のある解決策のようです。あなたはそれをこの解決策でグーグルできるかもしれません。

おそらく最善の策は、ある種のスクリプト(PHP、シェルなど)を使用して一時テーブルへのロードを実行し、次にストアドプロシージャを呼び出して、実際に永続テーブルにデータを入力することです。この部分のトランザクションサポートがあれば、本当に重要な部分(永続テーブルへの入力)をロールバックできると思います。

于 2012-12-25T00:04:05.713 に答える