插入触发器之前将重复行插入另一个表

rah*_*rma 2 mysql triggers

我有一个表tblspmaster,其中sp列我有唯一的索引,所以将不会插入重复项,但我想插入重复的行tblspduplicate.所以我决定为此写出触发器.在主表中,tblspmaster将使用Load File插入记录mysql

create trigger tblspmaster_noduplicate
before insert on tblspmaster
for each row
begin
  if ( select count(sp) from tblspmaster where sp=new.sp > 0 )then
    insert into tblspduplicate (sp,FileImported,AMZFileName)   values (NEW.sp,NEW.FileImported,NEW.AMZFileName)
  END
END
Run Code Online (Sandbox Code Playgroud)

我有问题清单

  1. 这是正确的方法来停止重复并插入另一个表吗?

  2. 我的触发器没有执行,因为它显示了一些语法错误

错误的反应是 Error Code: 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 'END END' at line 7

****************已编辑**************

这里是master和duplicate表的表定义以及触发器和加载数据文件的MySQL语句

CREATE TABLE IF NOT EXISTS `tblspmaster` (
  `CSN` bigint(20) NOT NULL AUTO_INCREMENT,
  `SP` varchar(10) NOT NULL,
  `FileImportedDate` date NOT NULL,
  `AMZFileName` varchar(50) NOT NULL,
  `CasperBatch` varchar(50) NOT NULL,
  `BatchProcessedDate` date NOT NULL,
  `ExpiryDate` date NOT NULL,
  `Region` varchar(50) NOT NULL,
  `FCCity` varchar(50) NOT NULL,
  `VendorID` int(11) NOT NULL,
  `LocationID` int(11) NOT NULL,
  PRIMARY KEY (`CSN`),
  UNIQUE KEY `SP` (`SP`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=10000000000 ;




   CREATE TABLE IF NOT EXISTS `tblspduplicate` (
      `SP` varchar(50) NOT NULL,
      `FileImportedDate` date NOT NULL,
      `AMZFileName` varchar(50) NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

use casper;
DELIMITER $$
create trigger tblspmaster_noduplicate
before insert on tblspmaster
for each row
begin
  if ( select count(sp) from tblspmaster where sp=new.sp > 0 ) then
    insert into tblspduplicate (sp,FileImportedDate,AMZFileName)   values (NEW.sp,NEW.FileImportedDate,NEW.AMZFileName);
  END IF;
END$$

DELIMITER ;






LOAD DATA local INFILE 'E://31october//SP//sp_files_sample1//400k sp00 6-19 E.csv'
INTO TABLE  tblspmaster
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
ESCAPED BY '\\'
LINES TERMINATED BY '\n'
IGNORE 1 LINES
(sp);
Run Code Online (Sandbox Code Playgroud)

这是故事的一个转折,我正在从ac#console应用程序执行此MySql命令,但我认为它不会以任何方式影响我们的数据库相关结构或程序.我还需要删除IGNORE 1 LINES语句,因为没有标题行.

pet*_*erm 7

就你引发的问题而言,有几个问题:

  1. ;插入语句后没有
  2. IF声明应END IF以分号结尾,而不仅仅是END
  3. 你必须用DELIMITER命令更改分隔符
  4. 使用EXISTS()而不是COUNT()

据说你的触发器看起来像

DELIMITER $$
CREATE TRIGGER tblspmaster_noduplicate
BEFORE INSERT ON tblspmaster
FOR EACH ROW
BEGIN
  IF (EXISTS(SELECT * FROM tblspmaster WHERE sp = NEW.sp)) THEN
    INSERT INTO tblspduplicate (sp,FileImported,AMZFileName)   
    VALUES (NEW.sp, NEW.FileImported, NEW.AMZFileName);
  END IF;
END$$
DELIMITER ;
Run Code Online (Sandbox Code Playgroud)

这是SQLFiddle演示

IGNORE在您的LOAD DATA INFILE陈述中使用条款.MySql会将错误(违反唯一约束)视为警告,有效地丢弃重复项.

LOAD DATA INFILE
如果指定IGNORE,则会跳过复制唯一键值上现有行的输入行.

LOAD DATA LOCAL INFILE 'E://31october//SP//sp_files_sample1//400k sp00 6-19 E.csv' 
IGNORE  
INTO TABLE tblspmaster 
FIELDS TERMINATED BY ',' ENCLOSED BY '"' ESCAPED BY '\\' 
LINES TERMINATED BY '\n' 
-- IGNORE 1 LINES
Run Code Online (Sandbox Code Playgroud)

注意: FYI重复行的插入失败将在auto_increment SCN列的值中留下空白.


您可以考虑另一种可能更优选的性能方法:

  1. 创建没有约束且没有索引的临时登台表
  2. 用于LOAD DATA INFILE填充登台表
  3. 拥有tblspmaster和临时表并使用INSERT ... SELECT语法tblspduplicate一次性插入所有重复项
  4. 从插入临时表仅是不存在的行成tblspmaster一气呵成再次
  5. TRUNCATE或DROP临时表