在BEGIN ... END上下文或外部和LOOP语法中启动TRANSACTION

Gre*_*een 5 mysql loops stored-procedures transactions

我有两个关于MySQL中的复合语句和事务的问题.

第一:

MySQL手册中有两个注释:

注意

在所有存储的程序中,解析器将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
Run Code Online (Sandbox Code Playgroud)

哪一种是正确的方式,第一种变体或第二种变体?

第二:

我不想创建存储过程或函数.我只想在常规流程中创建一个带有循环的Compound-Statement Block,如下所示:

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
Run Code Online (Sandbox Code Playgroud)

这种结构有可能吗?因为我抛出了一个错误:

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 ...
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  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
    
    Run Code Online (Sandbox Code Playgroud)
  3. BEGIN...END如果我只想使用,我是否必须使用LOOP?我可以LOOP不用启动就使用语法BEGIN...END吗?手册中唯一的例子LOOP是:

      CREATE PROCEDURE doiterate(p1 INT)
         BEGIN
           label1: LOOP
             ... 
    
    Run Code Online (Sandbox Code Playgroud)

egg*_*yal 13

  1. 是否允许在一般流程中使用BEGIN ... END而不创建和使用存储过程或函数?

    否:复合语句只能在存储程序的主体中使用.

  2. 它是允许在BEGIN...END里面使用START TRANSACTION...COMMIT还是我必须放在START TRANSACTION...COMMIT里面BEGIN...END

    START TRANSACTION;并且COMMIT;是单独的陈述.如果希望存储程序的主体包含多个语句,则需要将这些语句包含在某种复合语句块中BEGIN ... END(例如,类似于{ ... }在类C语言中用括号括起一个语句块).

    也就是说,你可以有一个只包含单一语句的存储程序,START TRANSACTION;或者这样COMMIT;一个程序不需要任何复合语句块,而只是分别开始新的/提交当前事务.

    在存储程序之外,不允许使用复合语句块,您可以在需要时发出START TRANSACTION;COMMIT;声明.

  3. BEGIN...END如果我只想使用,我是否必须使用LOOP?我可以LOOP不用启动就使用语法BEGIN...END吗?

    LOOP也是一个复合语句块,仅在存储过程中有效.没有必要LOOP块包含在块内BEGIN ... END,尽管通常是这样(否则很难执行任何所需的循环初始化).

在您的情况下,您显然希望从循环结构中将数据插入表中,您将需要:

  • 定义您使用的存储程序LOOP;

  • 迭代外部程序中的循环,该循环在每次迭代时执行数据库查询; 要么

  • 根据SQL可以直接操作的集合重新定义您的逻辑.