首先,我理解为什么我会收到此错误消息,而且我知道解决问题的方法,但我希望能提供比我想象的更有效的方法。这基本上就是我所拥有的:
UPDATE customer c
JOIN customer d ON c.customer_id = d.parent_customer_id
SET ?
WHERE d.customer_type = "Big Cheese";
因此,数据被输入到"?"参数如下所示:
{"customer_id": 10, "customer_name": "Cheese-It", ... }
问题是,因为我加入的是基本上自己的表,所有列都具有相同的名称。我知道如何解决这个问题的唯一方法是编辑JSON并使用所需的别名为所有字段添加前缀:
{"c.customer_id": 10, "c.customer_name": "Cheese-It", ... }
我希望有一种更优雅的方式来解决这个问题。有没有办法重构我的SQL,以便它知道我想要更新哪个表别名?有什么想法吗?
答案 0 :(得分:0)
子查询将执行您想要的操作,但实际上效率较低,因为WHERE
子句中的子查询通常是性能杀手。我觉得你必须将JSON解析为SQL,所以我只想在那时添加别名。
无论如何,作为参考,以下是如何重构SQL以不需要别名:
UPDATE customer
SET ?
WHERE customer_id IN (
SELECT c.customer_id
FROM customer c
JOIN customer d ON c.customer_id = d.parent_customer_id
WHERE d.customer_type = 'Big Cheese'
);
注意:这是未经测试的
修改强>
第二个想法,EXISTS
条款对于性能会略好一些:
UPDATE customer c
SET ?
WHERE EXISTS (
SELECT 1
FROM customer d
WHERE d.parent_customer_id = c.customer_id
AND d.customer_type = 'Big Cheese'
);
无论哪种方式都应该有效。只要您在更新中没有JOIN
,SET
列只能引用一个表,这样您就可以避免出现模糊的列名错误。
答案 1 :(得分:0)
我知道这是一个比较老的问题,但是我发现了一个更好的解决方案,并且没有影响性能。您可以在要更新的对象中的属性名称中添加别名。
这是帮助功能,用于使用别名转换标准属性名称。
const allowUpdate = ['name']
function addUpdateAlias(updated, alias) {
let validUpdate = {}
for (let p in updated) {
if (allowUpdate.indexOf(p) > -1) {
validUpdate[`${alias}.${p}`] = updated[p]
}
}
return validUpdate;
}
现在,使用上面的函数包装要更新的对象,并在更新中应用别名!
您的参数将为:[addUpdateAlias(customer, 'c')]
,以传递到原始查询中。