在重复键上给出无效令牌
On duplicate key gives Invalid token
我正在尝试通过 cdclient
从 table clientref
.
的数字更新 name_code
从 employee_migration
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.
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-the 正确指出的那样,您需要 MERGE command。我原来的解决方案实际上是错误的。
如果你使用 Firebird 服务器(没有说,但你的错误文本看起来像)那么你有 MERGE
命令。
然而,如果你使用Interbase服务器,那么我不知道你如何在那里写那个语句,然后查阅Interbase手册:http://docwiki.embarcadero.com/InterBase/2017/en/Statement_and_Function_Reference_(Language_Reference_Guide)
您可以在 IBExpert 中使用 服务 -> 服务器属性和日志 菜单检查您使用的服务器。
假设您使用 Firebird 2.1 或更高版本
- http://en.wikipedia.org/wiki/Merge_(SQL)
- https://www.firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-dml-merge.html
例如这样的事情:
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)
- 即 "many to many":对于 clientref
中的每一行,在 employee_migration
中可以有许多对应的行,反之亦然相反。
因此,您可能会使用 src
查询中的许多候选行来匹配和更新 employee_migration as dest
中的行。
- 根据 SQL 标准,它应该立即生成错误。
- 通过 Firebird 2.x 实现 - 它会一个接一个地执行这些更新,覆盖以前的更新,并且只有最后一个候选行的结果会保留。
我正在尝试通过 cdclient
从 table clientref
.
name_code
从 employee_migration
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.
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-the 正确指出的那样,您需要 MERGE command。我原来的解决方案实际上是错误的。
如果你使用 Firebird 服务器(没有说,但你的错误文本看起来像)那么你有 MERGE
命令。
然而,如果你使用Interbase服务器,那么我不知道你如何在那里写那个语句,然后查阅Interbase手册:http://docwiki.embarcadero.com/InterBase/2017/en/Statement_and_Function_Reference_(Language_Reference_Guide)
您可以在 IBExpert 中使用 服务 -> 服务器属性和日志 菜单检查您使用的服务器。
假设您使用 Firebird 2.1 或更高版本
- http://en.wikipedia.org/wiki/Merge_(SQL)
- https://www.firebirdsql.org/file/documentation/reference_manuals/fblangref25-en/html/fblangref25-dml-merge.html
例如这样的事情:
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)
- 即 "many to many":对于 clientref
中的每一行,在 employee_migration
中可以有许多对应的行,反之亦然相反。
因此,您可能会使用 src
查询中的许多候选行来匹配和更新 employee_migration as dest
中的行。
- 根据 SQL 标准,它应该立即生成错误。
- 通过 Firebird 2.x 实现 - 它会一个接一个地执行这些更新,覆盖以前的更新,并且只有最后一个候选行的结果会保留。