【问题标题】:Trying to learn MySQL and transactions尝试学习 MySQL 和事务
【发布时间】:2010-12-27 03:56:01
【问题描述】:

在过去的几天里,我尝试在 MySQL 中编写一个存储过程,但我遇到了一些麻烦。希望这里有人可以给我一些意见:)

我发布的示例是为 asp.Net Membership 提供程序创建一个新用户。我希望将电子邮件和密码发送到数据库并获得一个 int 返回以验证 userdeatils 是否已写入数据库。

我使用 MySQL DB 5.1(我认为)并将 SQL 写入网络界面。

我有 2 个附带问题,有人可以解释一下吗 :): 1)我使用了DELIMITER,但不知道它的作用。 2)我不确定我是否必须做其他事情然后设置 autocommit = 0 以使事务正常工作,或者我什至必须这样做。

我知道我可以使用 IF / ELSE 语句而不是事务,但我想用一个来了解它是如何工作的。 (我希望以后会经常使用它)

我无法工作的代码:

DELIMITER //

CREATE DEFINER=`websharp_dk`@`%` PROCEDURE `CreateUser`(
    IN _username VARCHAR(100),
    IN _Password VARCHAR(100))
    RETURNS INT

    BEGIN
    SET autocommit = 0;
    DECLARE return_value INT;

    BEGIN TRY
        START TRANSACTION
                INSERT INTO User 
                (Email
                ,Password
                ,Failed_Password_Count
                ,Creation_Date)
                VALUES
                (_username
                ,_Password
                ,0
                ,Datetime.Now())
            SET return_value = 1;
        COMMIT;
    END TRY

    BEGIN CATCH
        ROLLBACK
        SET return_value = 0;
    END CATCH

    BEGIN FINALLY
    RETURN return_value;
    END FINALLY 
    END//
DELIMITER ;

编辑: 我得到的错误信息是:

1064 - 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以获取在 'INT BEGIN SET autocommit = 0; 附近使用的正确语法;声明 return_value INT; ' 在第 4 行

【问题讨论】:

  • 你可能想为你的问题写一个更有意义的标题。
  • 错误是什么?您永远不需要在事务中包装单个操作,因此在这种情况下,事务根本不做任何事情。
  • 更改了标题以更好地描述问题。
  • 事务应该做的是设置return_value,所以如果失败则返回0。我知道这可以以更好的方式完成,但我需要了解交易。我得到的错误是:#1064 - 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以获取在 'INT BEGIN SET autocommit = 0; 附近使用的正确语法;声明 return_value INT; ' 在第 4 行

标签: mysql stored-procedures transactions


【解决方案1】:

要获得对事务的支持,请确保您使用的是 InnoDB 存储引擎而不是默认的 MyISAM。

就该代码本身而言,我的第一个问题是,为什么要将单个查询包装在事务中?另外,您看到了什么错误?

【讨论】:

  • 现在正在查找 InnoDB,谢谢。我刚刚发布了上面的错误,应该从一开始就这样做,对不起
  • 感谢有关数据库引擎的信息。看来我很幸运地得到了 InnoBD :)
【解决方案2】:

分隔符重新定义了用于结束 sql 语句的字符序列。整个创建过程是一个大语句,您需要告诉 MySQL 它在哪里结束(通常是 ';')。但是,由于您在 create procedure 语句的“主体”(BEGIN 和 END 之间)中有一堆其他语句都需要结束,因此您需要重新定义分隔符,这样您就不会在第一个';'。

如果不重新定义分隔符,MySQL 会认为创建过程语句看起来像这样,然后开始一个新语句:

CREATE DEFINER=`websharp_dk`@`%` PROCEDURE `CreateUser`(
    IN _username VARCHAR(100),
    IN _Password VARCHAR(100))
    RETURNS INT

    BEGIN
    SET autocommit = 0;

使用分隔符;在脚本末尾将分隔符更改回“;”并且不需要,尽管这样做是一种很好的做法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    • 1970-01-01
    相关资源
    最近更新 更多