5

MySQL の複合ステートメントとトランザクションについて 2 つの質問があります。

最初:

MySQL マニュアルには 2 つの注記があります。

ノート

すべてのストアド プログラム内で、パーサーは BEGIN [WORK] を BEGIN ... END ブロックの開始として扱います。このコンテキストでトランザクションを開始するには、代わりに START TRANSACTION を使用してください。

ノート

すべてのストアド プログラム (ストアド プロシージャと関数、トリガー、およびイベント) 内で、パーサーは BEGIN [WORK] を BEGIN ... END ブロックの開始として扱います。代わりに START TRANSACTION を使用して、このコンテキストでトランザクションを開始してください。

私は正確に何を意味するのか理解できません。?START TRANSACTIONの代わりに、BEGINまたは直後に配置する必要があることを意味します。BEGIN

// 1st variant:

BEGIN
   START TRANSACTION
   COMMIT
END


// 2nd variant:

START TRANSACTION
COMMIT
END

1 番目のバリアントと 2 番目のバリアント、どちらが正しい方法ですか?

2番目:

ストアド プロシージャまたは関数を作成したくありません。次のように、一般的なフローで内部にループを含む複合文ブロックを作成したいだけです。

USE 'someDb';
START TRANSACTION
   ... create table statement
   ... insert statement

// now I want to implement some insert/select statements using loop, I do as follows:

DELIMITER $
BEGIN
  SET @n = 1, @m = 2;
  lab1: LOOP

   ... some insert, select statements here

   END LOOP lab1;
END $
DELIMITER ;

END

COMMIT

このような構造は可能でしょうか?エラーがスローされるため:

Query: BEGIN SET @n = 1, @m = 2; lab1: LOOP SELECT ...
Error Code: 1064
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 'SET @n = 1, @m = 2;
lab1: LOOP SELECT ...

私の質問は次のとおりです。

  1. BEGIN...ENDストアド プロシージャや関数を作成して使用せずに、一般的なフローで使用することはできますか?
  2. BEGIN...ENDの内部で使用することは許可されていますか、START TRANSACTION...COMMITまたは内部に配置する必要がSTART TRANSACTION...COMMITありBEGIN...ENDますか?

    BEGIN
       START TRANSACTION
       COMMIT
    END
    
    // vs.
    
    START TRANSACTION
       BEGIN
       END
    COMMIT
    
  3. BEGIN...ENDだけ使いたい場合は必ず使わないといけないのLOOPですか?LOOP開始せずに構文を使用できますBEGIN...ENDか? のマニュアルの唯一の例LOOPは次のとおりです。

      CREATE PROCEDURE doiterate(p1 INT)
         BEGIN
           label1: LOOP
             ... 
    
4

1 に答える 1

13
  1. ストアド プロシージャや関数を作成して使用せずに、一般的なフローで BEGIN...END を使用することはできますか?

    いいえ: 複合ステートメントは、ストアド プログラムの本体内でのみ使用できます。

  2. BEGIN...ENDの内部で使用することは許可されていますか、START TRANSACTION...COMMITまたは内部に配置する必要がSTART TRANSACTION...COMMITありBEGIN...ENDますか?

    START TRANSACTION;COMMIT;は別個のステートメントです。ストアド プログラムの本体に複数のステートメントを含めたい場合は、これらのステートメントを のようなある種の複合ステートメント ブロックで囲む必要があります(これは、C に似た言語BEGIN ... ENDでステートメントのブロックを中かっこで囲むのと似ています)。{ ... }

    つまり、単一ステートメントのみを含むストアド プログラムを作成することも、複合ステートメント ブロックを必要とせず、それぞれ新しいトランザクションを開始するか、現在のトランザクションをコミットするだけのプログラムを作成することもできます。START TRANSACTION;COMMIT;

    複合ステートメント ブロックが許可されていないストアド プログラムの外では、必要に応じてSTART TRANSACTION;andCOMMIT;ステートメントを & として発行できます。

  3. BEGIN...ENDだけ使いたい場合は必ず使わないといけないのLOOPですか?LOOP開始せずに構文を使用できますBEGIN...ENDか?

    LOOPストアド プロシージャ内でのみ有効な複合ステートメント ブロックでもあります。ブロックをブロック内に囲む必要はありませんが、通常はそうです (そうしないと、必要なループの初期化を実行するのが難しくなります)。LOOPBEGIN ... END

あなたの場合、明らかにループ構造からテーブルにデータを挿入したい場合は、次のいずれかを行う必要があります。

  • を使用するストアド プログラムを定義しますLOOP

  • 各反復でデータベースクエリを実行する外部プログラムでループを反復します。また

  • SQL が直接操作できるセットの観点からロジックを再定義します。

于 2012-09-04T12:07:49.430 に答える