有没有办法在mysql中做这样的事情:
INSERT INTO <sometable> SET
someRow = inputSomeValue, someOtherRow = inputValue2 AND
call function1()
ON DUPLICATE KEY ID = inNewID AND
call function2();
基本上,我想在“clean”插入上调用一些外部mysql存储过程,如果插入被重复键阻塞,则调用其他一些过程。这可能在MySql中吗?
修改: 存储过程中的原始插入已经是ALREADY!
答案 0 :(得分:0)
要做类似的事情,你需要在存储过程本身,但你必须建立条件逻辑,你不能在这样的单个查询中做到这一点。
您可以在存储过程中执行以下操作:
DELIMITER $$
DROP FUNCTION IF EXISTS `dbname`.`ConditionalInsert` $$
CREATE FUNCTION `dbname`.`ConditionalInsert` (inputSomeValueVARCHAR(20), inputValue2 VARCHAR(20), oldID INT(10), inNewID INT(10)) RETURNS INT
BEGIN
DECLARE testval INT;
DECLARE returnval INT DEFAULT 0;
SELECT COUNT(1) INTO testval FROM dbname.sometable WHERE ID = oldID;
IF testval = 0 THEN
INSERT INTO dbname.sometable someRow, someOtherRow) VALUES (inputSomeValue, inputValue2);
CALL function1();
SET returnval = 1;
ELSE
UPDATE dbname.sometable SET ID = inNewID WHERE ID = oldID;
CALL function2();
SET returnval = 2;
END IF;
RETURN returnval;
END $$
DELIMITER ;
答案 1 :(得分:0)
没有。无法从INSERT语句调用存储过程。
有一种方法可以从INSERT语句调用存储的程序,但它必须是用户定义的函数,例如:
INSERT INTO sometable (col)
SELECT IF( user_defined_function() , 'abc' , 'abc' )
但是,无论生成的行是否抛出重复的键异常,都会调用该函数。也可以在ON DUPLICATE KEY子句中引用用户定义的函数。
INSERT INTO sometable (col1)
SELECT IF( user_defined_function() , 'abc' , 'abc' )
ON DUPLICATE KEY UPDATE col1 = IF( udf_duplicate() , VALUES(col1), VALUES(col1) )
请注意,使用这些结构存在二进制日志记录(行与语句)的问题,这些类型的语句可能不是“安全”进行复制。
所以我认为你真的不想采用这种方法。如果要插入单行,则最好执行INSERT ... ON DUPLICATE KEY UPDATE ...语句,然后检查受影响的行数。受影响的行值1将告诉您插入了一行,受影响的行值为2表示该行已更新,因此您可以有条件地调用所需的过程。
如果您总是希望在插入或更新任何行时调用这些存储过程中的操作,您可以考虑AFTER INSERT和AFTER UPDATE触发器。 (您需要进行测试以确保AFTER UPDATE触发器从ON DUPLICATE KEY UPDATE触发...在MySQL的旧版本中存在问题,其中未调用AFTER UPDATE触发器。)
编辑:
原始问题的最新更新指定此INSERT语句是在MySQL存储过程中执行的。
我会推荐这种方法:
DECLARE affected_rows INT;
INSERT INTO sometable (id,foo) VALUES (123,'bar')
ON DUPLICATE KEY UPDATE foo = VALUES(foo);
SELECT ROW_COUNT() INTO affected_rows;
IF affected_rows = 1 THEN
CALL stored_procedure_after_insert();
ELSE
CALL stored_procedure_after_update();
END IF;
问:那么,“更新”后受影响的行号将为0?
答:如果没有对任何行进行修改(通过INSERT ... ON DUPLICATE KEY UPDATE
语句,则ROW_COUNT()函数将返回0.
如果没有插入行,并且更新了单行,则ROW_COUNT()函数将返回2.
获取0和2之间的区别在于是否实际修改了行。当更新结果导致行与行的当前内容相同时(“未进行更改”),则ROW_COUNT()返回0.如果更新导致对行的更改,则ROW_COUNT()将是2。