如何解决如何使用 SQL 语句重命名 AzerothCore 上的 Warlock Minions?
我想编写一个 SQL 查询来重命名 AzerothCore 上的 Warlock Minion(s),但我的第一次尝试遇到了 MySQL 错误:
MySQL 错误 1093 - 无法在 FROM 子句中指定要更新的目标表
我的代码:
USE `acore_characters`;
SET @IMP := 416;
SET @IMP_NAME = 'NewImpName';
SET @OWNER_NAME = 'NameOfMyWarlock';
UPDATE `character_pet` SET name = @IMP_NAME WHERE `id` IN
(SELECT p.`id` FROM `character_pet` p INNER JOIN `characters` c ON p.`owner` = c.`guid`
WHERE c.`name` = @OWNER_NAME AND p.`entry`= @IMP);
解决方法
在 this answer on stackoverflow 的帮助下,现在可以正常工作了。
--------------------------
-- Variant (A): Outdated
--------------------------
USE `acore_characters`;
-- Warlock pet creatures
SET @IMP := 416;
SET @VOIDWALKER := 1860;
SET @SUCCUBUS := 1863;
SET @FELHUNTER := 417;
SET @FELGUARD := 17252;
-- Names
SET @OWNER_NAME := 'MyWarlockName';
SET @IMP_NAME :='NewImpName';
SET @VOIDWALKER_NAME := 'NewVoidwalkerNamen';
SET @SUCCUBUS_NAME := 'NewSuccubusName';
SET @FELHUNTER_NAME := 'NewFelhunterName';
SET @FELGUARD_NAME := 'NewFelguardName';
-- Update Imp Name
UPDATE `character_pet` SET name = @IMP_NAME WHERE `id` IN
(SELECT s.`id` FROM (SELECT p.`id` FROM `character_pet` p INNER JOIN `characters` c ON p.`owner` = c.`guid`
WHERE c.`name` = @OWNER_NAME AND p.`entry`= @IMP) s);
-- Update Voidwalker Name
UPDATE `character_pet` SET name = @VOIDWALKER_NAME WHERE `id` IN
(SELECT s.`id` FROM (SELECT p.`id` FROM `character_pet` p INNER JOIN `characters` c ON p.`owner` = c.`guid`
WHERE c.`name` = @OWNER_NAME AND p.`entry`= @VOIDWALKER) s);
-- Update Succubus Name
UPDATE `character_pet` SET name = @SUCCUBUS_NAME WHERE `id` IN
(SELECT s.`id` FROM (SELECT p.`id` FROM `character_pet` p INNER JOIN `characters` c ON p.`owner` = c.`guid`
WHERE c.`name` = @OWNER_NAME AND p.`entry`= @SUCCUBUS) s);
-- Update Felhunter Name
UPDATE `character_pet` SET name = @FELHUNTER_NAME WHERE `id` IN
(SELECT s.`id` FROM (SELECT p.`id` FROM `character_pet` p INNER JOIN `characters` c ON p.`owner` = c.`guid`
WHERE c.`name` = @OWNER_NAME AND p.`entry`= @FELHUNTER) s);
-- Update Felguard Name
UPDATE `character_pet` SET name = @FELGUARD_NAME WHERE `id` IN
(SELECT s.`id` FROM (SELECT p.`id` FROM `character_pet` p INNER JOIN `characters` c ON p.`owner` = c.`guid`
WHERE c.`name` = @OWNER_NAME AND p.`entry`= @FELGUARD) s);
-- Show result
SELECT p.`id`,p.`entry`,p.`name`,c.`name` AS `owner_name`
FROM `character_pet` p INNER JOIN `characters` c ON p.`owner` = c.`guid`
WHERE c.`name` = @OWNER_NAME;
我既不喜欢额外的嵌套 SELECT
,也不真正理解为什么 MySQL 在没有它的情况下会抱怨,因为内部 SELECT
的结果不受外部 UPDATE
的影响。以下变体使用来自 the answer below 的建议并在 JOIN
上执行更新。遗憾的是,我无法使用“多合一更新”方法,因为 AzerothCore 对 MySQL 的最低要求是 5.7,而 WITH ... VALUES
构造显然需要 8.x。
--------------------------
-- Variant (B): Current
--------------------------
USE `acore_characters`;
-- Names (parameters)
SET @OWNERNAME := 'MyWarlockName';
SET @IMPNAME :='NewImpName';
SET @VOIDWALKERNAME := 'NewVoidwalkerNamen';
SET @SUCCUBUSNAME := 'NewSuccubusName';
SET @FELHUNTERNAME := 'NewFelhunterName';
SET @FELGUARDNAME := 'NewFelguardName';
-- Warlock pet creatures (constants)
SET @IMP := 416;
SET @VOIDWALKER := 1860;
SET @SUCCUBUS := 1863;
SET @FELHUNTER := 417;
SET @FELGUARD := 17252;
-- Update Imp Name
UPDATE `character_pet` p INNER JOIN `characters` c ON p.`owner` = c.`guid`
SET p.`name` = @IMPNAME
WHERE p.`entry` = @IMP AND c.`name` = @OWNERNAME;
-- Update Voidwalker Name
UPDATE `character_pet` p INNER JOIN `characters` c ON p.`owner` = c.`guid`
SET p.`name` = @VOIDWALKERNAME
WHERE p.`entry` = @VOIDWALKER AND c.`name` = @OWNERNAME;
-- Update Succubus Name
UPDATE `character_pet` p INNER JOIN `characters` c ON p.`owner` = c.`guid`
SET p.`name` = @SUCCUBUSNAME
WHERE p.`entry` = @SUCCUBUS AND c.`name` = @OWNERNAME;
-- Update Felhunter Name
UPDATE `character_pet` p INNER JOIN `characters` c ON p.`owner` = c.`guid`
SET p.`name` = @FELHUNTERNAME
WHERE p.`entry` = @FELHUNTER AND c.`name` = @OWNERNAME;
-- Update Felguard Name
UPDATE `character_pet` p INNER JOIN `characters` c ON p.`owner` = c.`guid`
SET p.`name` = @FELGUARDAME
WHERE p.`entry` = @FELGUARD AND c.`name` = @OWNERNAME;
-- Show result
SELECT p.`id`,c.`name` AS `owner_name`
FROM `character_pet` p INNER JOIN `characters` c ON p.`owner` = c.`guid`
WHERE c.`name` = @OWNERNAME;
,
您根本不需要子查询,只需使用 JOIN
UPDATE character_pet p
INNER JOIN characters c
ON p.owner = c.guid
AND c.name = @OWNER_NAME
AND p.entry = @IMP
SET name = @IMP_NAME
如果您要进行多次更新,还可以加入 VALUES
语句
WITH vals(id,newname) AS (
VALUES (416,'NewImpName'),(1860,'NewVoidwalkerName')
(1863,'NewSuccubusName')
(417,'NewFelhunterName')
(17252,'NewFelguardName'))
UPDATE character_pet p
INNER JOIN vals v
ON p.entry = v.id
INNER JOIN characters c
ON p.owner = c.guid
AND c.name = 'MyWarlockName'
SET p.name = v.newname
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。