正在调试存储过程中的 mySQL 语法错误

Debuggin mySQL syntax error in stored procedure

我正在将此文件重定向到 mysql promt 以添加存储过程:

DROP PROCEDURE IF EXISTS make_transaction;

DELIMITER //

CREATE PROCEDURE make_transaction(IN v_quote_id INT, IN v_your_id INT)
BEGIN

    DECLARE v_is_seller BOOLEAN;
    DECLARE v_option_type BOOLEAN;
    DECLARE v_trader_id INT;
    DECLARE v_premium DOUBLE(18, 4);
    DECLARE v_offer_expires DATETIME;
    DECLARE v_instrument_id INT;

    DECLARE v_pretend_now DATETIME;

    DECLARE v_buyer_id INT;
    DECLARE v_seller_id INT;

    DECLARE v_buyer_total_balance DOUBLE(18, 4);

    SELECT
        instrument_id,
        trader_type,
        option_type,
        trader_id,
        premium,
        offer_expires
    INTO
        v_instrument_id,
        v_is_seller,
        v_option_type,
        v_trader_id,
        v_premium,
        v_offer_expires
    FROM
        option_quotes
    WHERE
        quote_id = v_quote_id;

    IF v_is_seller THEN
        SET v_seller_id = v_trader_id;
        SET v_buyer_id = v_your_id;
    ELSE
        SET v_buyer_id = v_trader_id;
        SET v_seller_id = v_your_id;
    END IF;


    -- Last STOCK_TRADE time is assumed to be the current time
    SELECT DATE_TIME
    INTO v_pretend_now
    FROM STOCK_TRADE
    WHERE INSTRUMENT_ID=v_instrument_id
    ORDER BY DATE_TIME DESC
    LIMIT 1;


    SELECT total_balance
    INTO v_buyer_total_balance
    FROM traders
    WHERE trader_id=v_buyer_id;


    IF offer_expires <= v_pretend_now THEN
        SELECT 'That offer has expired';
    ELSE IF v_buyer_total_balance < v_premium THEN
        SELECT 'You do not have enough money to transact on this offering';
    ELSE
        INSERT INTO option_transactions
        (
            transaction_time,
            quote_id,
            buyer_id,
            seller_id,
            buyer_gain,
            seller_gain
        )
        VALUES
        (
            v_pretend_now,
            v_quote_id,
            v_buyer_id,
            v_seller_id,
            NULL, -- line 85
            NULL
        );
    END IF;
END //

DELIMITER ;

我在尝试将存储过程输入 db 时收到错误:

ERROR 1064 (42000) at line 5: 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 '' at line 85

option_transactions table 看起来像这样:

+------------------+--------------+------+-----+---------+-------+
| Field            | Type         | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+-------+
| quote_id         | int(11)      | NO   | MUL | NULL    |       |
| buyer_id         | int(11)      | NO   | MUL | NULL    |       |
| seller_id        | int(11)      | NO   | MUL | NULL    |       |
| transaction_time | datetime     | NO   |     | NULL    |       |
| buyer_gain       | double(18,4) | YES  |     | NULL    |       |
| seller_gain      | double(18,4) | YES  |     | NULL    |       |
+------------------+--------------+------+-----+---------+-------+

我是 mySQL 的新手,但在第 85 行附近的 insert into 命令语法对我来说似乎是正确的,我不确定问题出在哪里。我该如何解决这个问题?

(mysql 服务器版本 5.5.42)

第 85 行不在 INSERT 语句的中间,它在 CREATE PROCEDURE 语句的末尾。如果我将您的代码粘贴到 vim 和 :se nu 中以显示行号,然后删除 CREATE PROCEDURE 之前的初始行,最后一行是第 85 行:

84     END IF;
85 END //
86
87 DELIMITER ;

因此错误中的行号从语句的第一行开始计算,而不是 SQL 脚本文件的第一行。

然后我去寻找,发现了一个不平衡的块:

IF offer_expires <= v_pretend_now THEN
ELSE IF v_buyer_total_balance < v_premium THEN
ELSE
END IF;

您在 ELSE 中使用了嵌套的 IF/THEN/ELSE/END IF。所以你实际上有 两个 IF 语句,但只有一个 END IF.

要解决此问题,您有两种选择:

  1. ELSIF:

    做一个 IF 语句
    IF offer_expires <= v_pretend_now THEN
    ELSEIF v_buyer_total_balance < v_premium THEN
    ELSE
    END IF;
    

    有关 IF/THEN/ELSIF/ELSE/END IF.

  2. 语法的文档,请参阅 https://dev.mysql.com/doc/refman/5.7/en/if.html
  3. 完成两个 IF 语句:

    IF offer_expires <= v_pretend_now THEN
    ELSE
        IF v_buyer_total_balance < v_premium THEN
        ELSE
        END IF;
    END IF;