2

我有一个名为tblspmastersp 列的表,其中我有唯一索引,因此不会插入重复项,但我想将重复的行插入tblspduplicate. 所以我决定为此编写触发器。tblspmaster将使用 Load File 插入作为记录的 IN 主表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

我有问题清单

  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

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

这是主表和重复表的表定义以及触发和加载数据文件 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);

这是我从 ac# 控制台应用程序执行这个 MySql 命令的故事的一个转折点,但我认为它不会以任何方式影响我们的 db 相关结构或程序。我还需要删除IGNORE 1 LINES语句,因为不会有标题行。

4

1 回答 1

7

就您的触发而言,存在几个问题:

  1. 你没有;after insert 语句
  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 ;

这是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

注意:仅供参考,重复行的插入失败将在 auto_incrementSCN列的值中留下空白。


您可以考虑另一种在性能方面可能更可取的方法:

  1. 创建没有约束和索引的临时登台表
  2. 用于LOAD DATA INFILE填充临时表
  3. 拥有tblspmaster和临时表并使用语法一次性INSERT ... SELECT插入所有重复项tblspduplicate
  4. tblspmaster一次性将临时表中不存在的行再次插入
  5. TRUNCATEDROP临时表
于 2013-09-04T18:41:07.057 回答