在重复的密钥上给出无效的令牌

时间:2018-07-23 10:12:36

标签: sql firebird

我正在尝试根据表name_codeemployee_migration的数字来更新cdclient中的clientref

 INSERT INTO employee_migration (name_code)
      Select cl.cdclient 
        From clientref cl 
  Inner Join employee_migration em  
          ON cl.client like upper(em.name)
          ON DUPLICATE KEY UPDATE name_code VALUES (cl.cdclient)

我收到此错误: 令牌无效。

Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 3, column 1.
ON.

2 个答案:

答案 0 :(得分:5)

如果您使用的是 Firebird 服务器(虽然没有说,但是看起来像您的错误文本),那么您可以使用MERGE命令。

但是,如果您使用 Interbase 服务器,那么我不知道如何在其中编写该语句,请查阅Interbase手册,然后:http://docwiki.embarcadero.com/InterBase/2017/en/Statement_and_Function_Reference_(Language_Reference_Guide)

您可以使用服务->服务器属性和日志菜单在 IBExpert 中检查要使用的服务器。

假设您使用Firebird 2.1版或更高版本

例如这样的东西:

MERGE INTO employee_migration dest
USING (
      Select cl.cdclient, em.ID
        From clientref cl 
  Inner Join employee_migration em  
          ON cl.client like upper(em.name)
      ) as src
ON dest.ID = src.ID -- or whatever your key columns are

WHEN MATCHED THEN UPDATE SET dest.namecode = src.cdclient

WHEN NOT MATCHED THEN INSERT (namecode, ID, ....)
    VALUES ( src.cdclient, ...., ...........)

但是,如果没有示例数据,您的请求似乎没有什么实际意义。

您的join条件为cl.client like upper(em.name)-“多对多”:对于clientref中的每一行,employee_migration中可以有许多对应的行,反之亦然。

因此,您可能会将employee_migration as dest查询中的许多候选行与src中的行进行匹配和更新。

  • 按照SQL标准,它应该立即产生错误。
  • 通过Firebird 2.x实施-它会依次进行这些更新,覆盖以前的更新,并且只有最后一个候选行的结果才会保留。

答案 1 :(得分:1)

Firebird与MySQL的语法不同

MERGE INTO employee_migration
  USING (Select cl.cdclient 
    From clientref cl 
    Inner Join employee_migration em ON cl.client like upper(em.name)) AS tmp
  ON employee_migration.name_code = tmp.cdclient
  WHEN MATCHED THEN UPDATE SET name_code = tmp.cdclient
  WHEN NOT MATCHED THEN INSERT (name_code) VALUES(tmp.cdclient)

更新

正如@arioch-正确指出的那样,您需要MERGE command。我原来的解决方案实际上是错误的。