5

我有两个关于 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

哪一个是正确的方法,第一个变体或第二个变体?

第二:

我不想创建存储过程或函数。我只想在一般流程中创建一个带有循环的复合语句块,如下所示:

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...ENDinside ofSTART TRANSACTION...COMMIT或我必须放入START TRANSACTION...COMMITinside of 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...ENDinside ofSTART TRANSACTION...COMMIT或我必须放入START TRANSACTION...COMMITinside of 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 可以直接操作的集合重新定义您的逻辑。

于 2012-09-04T12:07:49.430 回答