正在调试存储过程中的 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
.
要解决此问题,您有两种选择:
用 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
.
语法的文档,请参阅 https://dev.mysql.com/doc/refman/5.7/en/if.html
完成两个 IF
语句:
IF offer_expires <= v_pretend_now THEN
ELSE
IF v_buyer_total_balance < v_premium THEN
ELSE
END IF;
END IF;
我正在将此文件重定向到 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
.
要解决此问题,您有两种选择:
用
做一个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
. 语法的文档,请参阅 https://dev.mysql.com/doc/refman/5.7/en/if.html
完成两个
IF
语句:IF offer_expires <= v_pretend_now THEN ELSE IF v_buyer_total_balance < v_premium THEN ELSE END IF; END IF;