在更新前使用触发器将一行插入到我的第二个表中

Posted

技术标签:

【中文标题】在更新前使用触发器将一行插入到我的第二个表中【英文标题】:Using a trigger BEFORE UPDATE to INSERT a row into my second table 【发布时间】:2015-05-11 22:59:17 【问题描述】:

我将这个作为我的pension_accounts 表的表结构,并在我的第二个表pension_statement 表的结构下方从表pension_accounts AFTER UPDATE 触发器中进行选择

Table structure for table `pension_accounts` 

CREATE TABLE IF NOT EXISTS `pension_accounts` (
  `User_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `Title` varchar(500) NOT NULL,
  `Surname` varchar(500) NOT NULL,
  `Firstname` varchar(500) NOT NULL,
  `Other_names` varchar(500) NOT NULL,
  `DOB` varchar(500) NOT NULL,
  `Gender` varchar(500) NOT NULL,
  `MaritalStatus` varchar(500) NOT NULL,
  `City` varchar(500) NOT NULL,
  `State` varchar(500) NOT NULL,
  `Nationality` varchar(500) NOT NULL,
  `Country` varchar(500) NOT NULL,
  `Email` varchar(500) NOT NULL,
  `Mobile` varchar(500) NOT NULL,
  `Address` varchar(500) NOT NULL,
  `AccountType` varchar(500) NOT NULL,
  `PASSWORD` varchar(500) NOT NULL,
  `ACCOUNT_NUMBER` varchar(500) NOT NULL DEFAULT '',
  `CountryCode` varchar(500) NOT NULL,
  PRIMARY KEY (`User_id`),
  UNIQUE KEY `Surname` (`Surname`,`Firstname`,`PASSWORD`),
  UNIQUE KEY `Email` (`Email`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

DROP TRIGGER IF EXISTS `before_update_pension_accounts`;
DELIMITER //
CREATE TRIGGER `before_update_pension_accounts` BEFORE UPDATE ON `pension_accounts`
 FOR EACH ROW SET new.Modified_DateTime = CURRENT_TIMESTAMP
//
DELIMITER ;

第二张表`

pension_statement的表结构

CREATE TABLE IF NOT EXISTS `statement` (
  `StatementID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `Statement_Surname` varchar(500) NOT NULL,
  `Statement_Firstname` varchar(500) NOT NULL,
  `Statement_ACCOUNT_NUMBER` varchar(500) NOT NULL,
  `Statement_Balance` varchar(500) NOT NULL,
  `Statement_Modified_DateTime` varchar(500) NOT NULL,
  `Statement_Description` varchar(500) NOT NULL,
  `Statement_CurrencyType` varchar(500) NOT NULL,
  PRIMARY KEY (`StatementID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

问题: 我尝试向该触发器添加一条 INSERT 语句以在 pension_statement 中插入一行,但它失败了;

DROP TRIGGER IF EXISTS `statement_history`;
DELIMITER //
CREATE TRIGGER `statement_history` AFTER UPDATE ON `pension_accounts`
 FOR EACH ROW INSERT INTO `pension_statement` (`StatementID`, `Statement_Surname`, `Statement_Firstname`, `Statement_ACCOUNT_NUMBER`, `Statement_Balance`, `Statement_Modified_DateTime`) VALUES (NULL, 'new.Statement_Surname', 'new.Statement_Firstname', 'new.Statement_ACCOUNT_NUMBER', 'new.Statement_Balance', 'new.Statement_Modified_DateTime')
//
DELIMITER ;

它返回这个值:

'new.Statement_Surname', 'new.Statement_Firstname', 'new.Statement_ACCOUNT_NUMBER', 'new.Statement_Balance', 'new.Statement_Modified_DateTime'

【问题讨论】:

您的问题/问题是什么? 您可以将语句添加到现有触发器。当前触发器是否有效,用于设置 TIMESTAMP?您可以向该触发器添加一条 INSERT 语句,以便在第二个表中插入一行。 @dubstylee 是的,触发器工作正常,我只需要知道如何向该触发器添加一个 INSERT 语句,以便在第二个表中插入一行。 您可以通过将 then 括在 begin ... end 块中来创建复合语句 @pala_ 它没有选择插入到行中的内容以便重新插入到表中 Pension_statement 【参考方案1】:

您可以在触发器中执行多个语句,方法是将其包含在 begin ... end 块中。例如。

DROP TRIGGER IF EXISTS `before_update_pension_accounts`;
DELIMITER //
CREATE TRIGGER `before_update_pension_accounts` BEFORE UPDATE ON `pension_accounts`
 FOR EACH ROW 
 BEGIN
   SET new.Modified_DateTime = CURRENT_TIMESTAMP;
   ... another statement here ... ;
   ... and another one ... ;
 END
//
DELIMITER ;

所以只需在set 语句之后添加您的insert 语句,并确保它位于beginend 内。

好的,现在我们有了更多信息,很明显您想要的是after insert 触发器。它应该是这样的:

CREATE TRIGGER `before_update_pension_accounts` after insert ON `pension_accounts`
FOR EACH ROW 
BEGIN
   insert into `statement` (statement_surname, statement_firstname, statement_account_number, statement_balance, statement_modified_datetime, statement_description, statement_currencytype) values(new.surname, new.firstname, new.account_number, 0, now(), 'something', 'something');
END//

在这种情况下,您只能使用new 前缀来引用pension_accounts 表中的字段,这意味着必须将statement_balancestatement_descriptionstatement_currencytype 设置为某个默认值。 statement_modified_datetime可以设置为当前时间。

here is a demo 显示此过程正在运行。

我假设,由于没有描述您要完成的工作,您是否想在开设新帐户后设置一份声明?如果不是这种情况,请返回问题并描述您想要完成的任务,而不是仅仅向我们展示您正在尝试的内容。

【讨论】:

有人请帮我解决问题 按照您的指示删除引号后,它返回列 field_name 作为值,这是错误 你想在触发器的语句表中插入什么? 与触发器更新的值相同,我想选择新值作为更新并插入到新表中 您的pension_statement 表没有您尝试插入的字段。它永远不会起作用。您是否在表定义中留下了字段?您显示了一个引用 surname 字段的复合键,但 pension_statement 的表定义不包含 surname 字段。

以上是关于在更新前使用触发器将一行插入到我的第二个表中的主要内容,如果未能解决你的问题,请参考以下文章

使用触发器将值插入另一个表,除非值存在,在这种情况下更新

如何从内部连接的第二个表中按列选择前 1 个顺序 desc?

如何使用 laravel 集合获取最后插入的 ID 并将其插入到第二个表中?

如何在新表中插入受影响的行

列更新时的 SQL mariaDB 触发器

帮助 mysql 触发器(插入前检查值)