MySQL触发器怎么变相使用动态SQL?

知行旅人 发布于 2015/05/14 16:00
阅读 2K+
收藏 0
-- --------------------------------------------------------------------------------------------------------
-- TRIGGER
-- --------------------------------------------------------------------------------------------------------
DROP TRIGGER IF EXISTS TR_after_insert_temp_log;
DELIMITER ;;
CREATE TRIGGER TR_after_insert_temp_log AFTER INSERT ON temp_log FOR EACH ROW
BEGIN

SET @table = NEW.table;
SET @column = NEW.column;
SET @num = NEW.num;
SET @where = NEW.where;

CALL SP_OF_TR_after_insert_temp_log(
    @table ,
    @column,
    @num,
    @where
);

END
;;

DELIMITER ;

-- --------------------------------------------------------------------------------------------------------
-- PROCEDURE
-- --------------------------------------------------------------------------------------------------------
DROP PROCEDURE IF EXISTS SP_OF_TR_after_insert_temp_log;
DELIMITER ;;
CREATE PROCEDURE SP_OF_TR_after_insert_temp_log(
    IN sp_table varchar(100),
    IN sp_column varchar(100),
    IN sp_num int(11),
    IN sp_where varchar(1000)
) SQL SECURITY INVOKER
BEGIN
    DECLARE sqlstr varchar(2000);
    -- 拼接SQL语句
    SET sqlstr = CONCAT('UPDATE ',sp_table,' SET ',
        sp_column,' = ',sp_column,' + ',sp_num,
        ' WHERE ',sp_where);
    SET @sql = sqlstr;
    PREPARE presql FROM @sql;
    EXECUTE presql;
    DEALLOCATE PREPARE presql;
END
;;
DELIMITER ;

-- --------------------------------------------------------------------------------------------------------
-- Run Result
-- --------------------------------------------------------------------------------------------------------

2015-5-14 15:33:13 org.apache.catalina.core.StandardWrapperValve invoke
严重: Servlet.service() for servlet spring threw exception
java.sql.SQLException: Dynamic SQL is not allowed in stored function or trigger
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1094)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4226)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4158)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2615)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2776)
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2840)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2082)
    at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1302)
    at com.jolbox.bonecp.PreparedStatementHandle.execute(PreparedStatementHandle.java:140)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:62)
    at com.sun.proxy.$Proxy320.execute(Unknown Source)

我知道MySQL的触发器不支持动态SQL,我想知道有没有变相的办法来做这个事儿?可以说说你的思路,谢谢!

加载中
0
知行旅人
知行旅人

现在有两个办法:

1、一个是直接调用存储过程,因为mysql的存储过程还是支持动态sql的

2、一个是通过MyBatis直接动态传入参数包括表名、字段名等等

0
知行旅人
知行旅人
额,刚才那个朋友的评论怎么不见了?
返回顶部
顶部