mysql插入触发错误
mysql insert trigger error
我刚转到 phymysql,但在创建触发器时遇到了问题。下面是我的脚本
CREATE TRIGGER trgAutoInsert AFTER INSERT ON profile
FOR EACH ROW
BEGIN
DECLARE var1 INT;
DECLARE var2 INT;
DECLARE var3 CHAR(100);
DECLARE var4 CHAR(100);
DECLARE var5 CHAR(3);
SELECT profile_id,
profile_id,
fname,
fname,
fpage
FROM profile
INTO var1,
var2,
var3,
var4,
var5;
IF var5 = 'yes'
THEN
INSERT INTO fiends
(req_id, resp_id, req_name, resp_name, fpage)
VALUES
(var1, var2, var3, var4, 'yes');
END IF;
END
当我执行时出现这个错误
#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 '' at line 5
如有任何帮助,我将不胜感激。
在 MySQL 中执行此操作的典型方法使用 :=
:
SELECT var1 := profile_id,
var2 := profile_id,
var3 := fname,
var4 := fname,
var5 := fpage
FROM profile;
在我看来,into
子句与 Oracle 类似。
也就是说,有两点需要注意:
- 这似乎假设
profile
只有一行。通常会有一个 where
子句。
- 你应该用前缀命名你的变量(比如
v_
),这样它们就不会与列混淆。
但是,我会在没有变量的情况下写这个:
DELIMITER $$
CREATE TRIGGER trgAutoInsert AFTER INSERT ON profile
FOR EACH ROW
BEGIN
INSERT INTO fiends(req_id, resp_id, req_name, resp_name, fpage)
SELECT profile_id, profile_id, fname, fname
FROM profile p
WHERE fpage = 'yes';
END$$
DELIMITER ;
这看起来简单多了。我猜 yes
应该是一个字符串。
编辑:
如果你想要刚刚插入的行,使用new
:
DELIMITER $$
CREATE TRIGGER trgAutoInsert AFTER INSERT ON profile
FOR EACH ROW
BEGIN
INSERT INTO fiends(req_id, resp_id, req_name, resp_name, fpage)
SELECT new.profile_id, new.profile_id, new.fname, new.fname
FROM dual
WHERE new.fpage = 'yes';
END$$
DELIMITER ;
我怀疑问题出在语句分隔符上;我怀疑它仍然设置为分号字符。
因为触发器包含分号字符,要将"create trigger"语句与运行作为一个单元,您需要将分隔符更改为不在[=中的任何位置出现的字符串33=] 语句
例如:
-- change the statement delimiter to something other than semicolon
DELIMITER $$
-- execute the "create trigger" statement containing semicolons
CREATE TRIGGER ...
BEGIN
... ;
... ;
IF ( ... ) THEN
... ;
END IF;
... ;
END$$
-- the occurrence of the $$ delimiter on the line above ends the statement
-- change the delimiter back to semicolon
DELIMITER ;
此外,我认为触发器不允许 select 来自刚刚插入的同一个 table。 (我知道这是对 Oracle 中 FOR EACH ROW 触发器的限制;我必须查阅 MySQL 参考手册才能确定...有一个关于 "restrictions on mysql stored programs" 的部分,过程是最自由的,函数与过程有相同的限制,而且更多,触发器与函数有相同的限制,还有更多。
此外,当该触发器执行时(如果允许从同一个 table select),该 SELECT 语句可能 return 不止一个排。使用 INTO
形式,我们预计最多有一行被 returned.
如果目的是引用刚刚插入的行的值,并在插入到另一个 table fiends
(或 friends
?)
使用 NEW.column_name
形式引用值
例如:
DELIMITER $$
CREATE TRIGGER profile_ai
AFTER INSERT ON profile
FOR EACH ROW
BEGIN
IF ( NEW.fpage = 'yes' ) THEN
-- are some of your friends fiends ?
INSERT INTO fiends
( req_id
, resp_id
, req_name
, resp_name
, fpage
) VALUES
( NEW.profile_id
, NEW.profile_id
, NEW.fname
, NEW.fname
, 'yes'
);
END IF;
END$$
DELIMITER ;
我刚转到 phymysql,但在创建触发器时遇到了问题。下面是我的脚本
CREATE TRIGGER trgAutoInsert AFTER INSERT ON profile
FOR EACH ROW
BEGIN
DECLARE var1 INT;
DECLARE var2 INT;
DECLARE var3 CHAR(100);
DECLARE var4 CHAR(100);
DECLARE var5 CHAR(3);
SELECT profile_id,
profile_id,
fname,
fname,
fpage
FROM profile
INTO var1,
var2,
var3,
var4,
var5;
IF var5 = 'yes'
THEN
INSERT INTO fiends
(req_id, resp_id, req_name, resp_name, fpage)
VALUES
(var1, var2, var3, var4, 'yes');
END IF;
END
当我执行时出现这个错误
#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 '' at line 5
如有任何帮助,我将不胜感激。
在 MySQL 中执行此操作的典型方法使用 :=
:
SELECT var1 := profile_id,
var2 := profile_id,
var3 := fname,
var4 := fname,
var5 := fpage
FROM profile;
在我看来,into
子句与 Oracle 类似。
也就是说,有两点需要注意:
- 这似乎假设
profile
只有一行。通常会有一个where
子句。 - 你应该用前缀命名你的变量(比如
v_
),这样它们就不会与列混淆。
但是,我会在没有变量的情况下写这个:
DELIMITER $$
CREATE TRIGGER trgAutoInsert AFTER INSERT ON profile
FOR EACH ROW
BEGIN
INSERT INTO fiends(req_id, resp_id, req_name, resp_name, fpage)
SELECT profile_id, profile_id, fname, fname
FROM profile p
WHERE fpage = 'yes';
END$$
DELIMITER ;
这看起来简单多了。我猜 yes
应该是一个字符串。
编辑:
如果你想要刚刚插入的行,使用new
:
DELIMITER $$
CREATE TRIGGER trgAutoInsert AFTER INSERT ON profile
FOR EACH ROW
BEGIN
INSERT INTO fiends(req_id, resp_id, req_name, resp_name, fpage)
SELECT new.profile_id, new.profile_id, new.fname, new.fname
FROM dual
WHERE new.fpage = 'yes';
END$$
DELIMITER ;
我怀疑问题出在语句分隔符上;我怀疑它仍然设置为分号字符。
因为触发器包含分号字符,要将"create trigger"语句与运行作为一个单元,您需要将分隔符更改为不在[=中的任何位置出现的字符串33=] 语句
例如:
-- change the statement delimiter to something other than semicolon
DELIMITER $$
-- execute the "create trigger" statement containing semicolons
CREATE TRIGGER ...
BEGIN
... ;
... ;
IF ( ... ) THEN
... ;
END IF;
... ;
END$$
-- the occurrence of the $$ delimiter on the line above ends the statement
-- change the delimiter back to semicolon
DELIMITER ;
此外,我认为触发器不允许 select 来自刚刚插入的同一个 table。 (我知道这是对 Oracle 中 FOR EACH ROW 触发器的限制;我必须查阅 MySQL 参考手册才能确定...有一个关于 "restrictions on mysql stored programs" 的部分,过程是最自由的,函数与过程有相同的限制,而且更多,触发器与函数有相同的限制,还有更多。
此外,当该触发器执行时(如果允许从同一个 table select),该 SELECT 语句可能 return 不止一个排。使用 INTO
形式,我们预计最多有一行被 returned.
如果目的是引用刚刚插入的行的值,并在插入到另一个 table fiends
(或 friends
?)
使用 NEW.column_name
形式引用值
例如:
DELIMITER $$
CREATE TRIGGER profile_ai
AFTER INSERT ON profile
FOR EACH ROW
BEGIN
IF ( NEW.fpage = 'yes' ) THEN
-- are some of your friends fiends ?
INSERT INTO fiends
( req_id
, resp_id
, req_name
, resp_name
, fpage
) VALUES
( NEW.profile_id
, NEW.profile_id
, NEW.fname
, NEW.fname
, 'yes'
);
END IF;
END$$
DELIMITER ;