代码之家  ›  专栏  ›  技术社区  ›  Catalina

在重复键上给出无效标记

  •  1
  • Catalina  · 技术社区  · 6 年前

    我正在尝试更新 name_code employee_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 回复  |  直到 6 年前
        1
  •  5
  •   Arioch 'The    6 年前

    如果你使用 火鸟 服务器(没有说,但看起来像你的错误文本),那么你有 MERGE 命令。

    但是,如果您使用 数据库 服务器,那么我不知道你怎么能在那里写下这句话,请查阅银行间手册,然后: 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实现,它将一个接一个地执行这些更新,覆盖以前的更新,并且只有最后一个候选行才会保留它们的结果。
        2
  •  1
  •   IVO GELOV    6 年前

    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 . 我原来的解决方案实际上是错误的。