根据插入的行

时间:2015-08-24 07:00:09

标签: mysql triggers alter-table

我在数据库中有两个表,其名称如下:

1. state_master
+---------------+-------------------+
|      state_id |        state_name |
+---------------+-------------------+
|             1 |               new |
|             2 |          assigned |
|             3 |       in_progress |
|             4 |           on_hold |
|             5 |            closed |
+---------------+-------------------+



2. store_complaint_state_count
+----------+-----+--------+------------+-------+------+
| store_id | new |assigned| in_progress|on_hold|closed|          
| 101      | 1   |2       | 2          |0      |0     |
| 102      | 5   |4       | 1          |0      |2     |
+----------+-----+--------+------------+-------+------+

现在我想在state_master state_id = 6和state_name = reopen中添加另一行。 我想创建一个触发器,它可以改变表store_complaint_state_count并在其中添加列重新打开。

我创建了一个程序:

CREATE DEFINER=`root`@`localhost` PROCEDURE `alterTablestorewisecomplaintcount`(in state int )
BEGIN
    alter table storewisecomplaintcount
    add column state INT UNSIGNED ZEROFILL NOT NULL DEFAULT 0;

END

触发器:

CREATE DEFINER = CURRENT_USER
    TRIGGER `nxtlife_sfcms_db_v2`.`complaint_state_AFTER_INSERT`
    AFTER INSERT ON `complaint_state`

FOR EACH ROW

BEGIN

call alterTablestorewisecomplaintcount(new.state_value);

END

但它在插入时会抛出错误:

  

错误1422:1422:存储函数或触发器中不允许显式或隐式提交。

2 个答案:

答案 0 :(得分:1)

您不能对触发器执行ALTER或DROP操作。这些是您在错误消息中看到的隐式提交(请参阅更多详细信息here

即使通过某种解决方法可能,这也是错误的设计。如果你能做你想做的事情 - 第一次插入表会添加列,从那时起 - 所有其他插入都会失败,因为列已经存在

答案 1 :(得分:0)

您好,您可以创建表并记录表中的所有事件。

create table dbLOG (Id Int Identity(1,1),PostTime 
VARCHAR(50),ServerName VARCHAR(25),UserName VARCHAR(15),CommandText 
   VARCHAR(MAX))
        go

                CREATE TRIGGER [db_LOG]
                ON DATABASE 
                FOR create_table,alter_table,drop_table
                ,create_PROCEDURE, alter_PROCEDURE,drop_PROCEDURE
                ,ALTER_function,create_function,drop_function
                ,ALTER_trigger,create_trigger,drop_trigger
               AS
               SET NOCOUNT ON
               DECLARE @xEvent XML
            SET @xEvent = eventdata() --capture eventdata regarding SQL statement user have fired
            INSERT INTO dbLOG VALUES(
            REPLACE(CONVERT(VARCHAR(50), @xEvent.query('data(/EVENT_INSTANCE/PostTime)')),'T', ' '),
            CONVERT(VARCHAR(25), @xEvent.query('data(/EVENT_INSTANCE/ServerName)')),
            CONVERT(VARCHAR(15), @xEvent.query('data(/EVENT_INSTANCE/UserName)')),
            CONVERT(VARCHAR(MAX), @xEvent.query('data(/EVENT_INSTANCE/TSQLCommand/CommandText)'))
            )