插入...在重复更新 - 主要创建重复

时间:2016-08-04 19:00:06

标签: mysql

目标表具有主键和唯一的复合索引(Name + UserNo + Title)。如果我手动添加副本,我将收到错误消息。但是,如果我运行存储过程,它会快速添加重复项,就好像没有唯一索引一样。

CREATE TABLE `tlk_employee_test` (
  `PK_ID` mediumint(9) NOT NULL AUTO_INCREMENT,
  `Name` varchar(25) NOT NULL,
  `UserNo` smallint(4) NOT NULL,
  `Department` varchar(55) NOT NULL,
  `Branch` varchar(25) NOT NULL,
  `BranchNo` smallint(6) NOT NULL,
  `Email` varchar(65) DEFAULT NULL,
  `Title` varchar(25) NOT NULL,
  `DateTimeStamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `Inactivated` tinyint(4) DEFAULT '0',
  `Incentivized` tinyint(4) DEFAULT '0',
  `Date_Modified` timestamp NOT NULL DEFAULT,
  PRIMARY KEY (`PK_ID`),
  UNIQUE KEY `idx_Name_UserNo_Title` (`Name`,`UserNo`,`Title`)
) ENGINE=InnoDB AUTO_INCREMENT=209 DEFAULT CHARSET=utf8;


INSERT INTO tlk_employee_test(`Name`, UserNo, Department, Branch, BranchNo, Email, Title, Inactivated, Incentivized) 
SELECT t.* FROM
  (
    SELECT s.UserName AS `Name`, s.UserNo, ad.Department, s.Branch, s.BranchNo, ad.Email, ad.Title, s.Inactivated, ad.Incentivized 
    FROM tmp_imported_ad_employees ad INNER JOIN tmp_imported_symitar_employees s ON ad.`Name` = s.UserName 
  ) AS t 
ON DUPLICATE KEY UPDATE Department = t.Department, Branch = t.Branch, BranchNo = t.BranchNo, Email = t.Email, Inactivated = t.Inactivated;

所以Select包含这样的记录: Jeanice Smith,109,Accounting,Aurora,4,SmithJ @ finsv.org,FSR,0,1

tlk_employee中存在一条记录,如下所示: Jeanice Smith,109,Accounting,Aurora,4,SmithJ @ finsv.org,FSR,0,1

...并且在存储的proc运行之后,tlk_employee有一个副本: Jeanice Smith,109,Accounting,Aurora,4,SmithJ @ finsv.org,FSR,0,1 Jeanice Smith,109,Accounting,Aurora,4,SmithJ @ finsv.org,FSR,0,1

我是否包含PK_ID似乎无关紧要。结果相同。我尝试使用Values()但结果相同。我在临时表中更改了单个记录的分支编号,并且tlk_employee记录执行了更新,并且没有创建重复记录。我对上面的记录进行了相同的更改,并创建了一个重复的记录,除了分支号码是我改变它但其他记录没有更新。 ???困惑......任何帮助表示赞赏。这是这个问题的第四天。

1 个答案:

答案 0 :(得分:0)

非打印字符对ON DUPLICATE KEY很重要,从技术上讲,它们与UNIQUE KEY(“触发”/ ON DUPLICATE KEY检查有关。这样的人物一次。这些字符可以从很多地方输入您的数据;它们可以从格式不良(或已解析)的源文件导入,通过用户输入未过滤此类字符或行为不当的客户端应用程序。

某些类型(和位置)的字符比其他字符更容易检查/更正。通常可以使用TRIM MySQL函数来校正典型的“空格”字符(如制表符和换行符,如前导和/或尾随)(并且可以通过将其结果与原始字段值进行比较来检测)。

不常见的非打印字符或字符串中间的字符可能更难以处理。找到它们通常需要使用正则表达式,修复它们通常可以是半手动过程。最多涉及使用REPLACE()CHAR()等字符串函数的查询。

可以创建一个存储过程或函数,它可以循环并分别检查每个非打印字符并修复或返回字符串的固定版本;但根据我的经验,需要手动处理需要此类修复的数据才能完全修复;例如“合并”(或以其他方式解析)对应该重复的行的引用,或者甚至能够在执行此操作时实际更正该值将导致UNIQUE KEY违规。