#mysql #common-table-expression #linq2db
#mysql #common-table-expression #linq2db
Вопрос:
Этот вопрос касается linq2db.MySQL 3.1.5 и MySQL 8.0.21
Я получаю сообщение «У вас ошибка в вашем синтаксисе SQL …» при попытке запустить обновление (помечая повторяющиеся электронные письма) с использованием CTE в MySQL, как указано ниже
var cte = (
from x in db.GetTable<PEmailCleanupJobItem>()
group x by x.EmailAddress into eGroup
where eGroup.Count() > 1
select new { EmailAddress = eGroup.Key }
).AsCte();
var qry = (
from e in db.GetTable<PEmailCleanupJobItem>()
from d in cte
.InnerJoin(d => e.EmailAddress == d.EmailAddress)
select e
);
await qry
.Set(e => e.IsDuplicate, true)
.UpdateAsync();
Это генерирует и отправляет в MySQL следующее
-- MySql.Official MySql (asynchronously)
DECLARE @IsDuplicate UByte -- Boolean
SET @IsDuplicate = 1
UPDATE `CTE_1` (`EmailAddress`)
AS
(
SELECT
`t1`.`email_address`
FROM
`emails` `t1`
GROUP BY
`t1`.`email_address`
HAVING
Count(*) > 1
)
FROM
`emails` `d`
INNER JOIN `CTE_1` `e` ON (`d`.`email_address` IS NULL AND `e`.`EmailAddress` IS NULL OR `d`.`email_address` = `e`.`EmailAddress`)
SET
`d`.`is_duplicate` = @IsDuplicate
Обратите внимание, как UPDATE `CTE_1` (`EmailAddress`)
генерируется вместо WITH `CTE_1` (`EmailAddress`)
Я бы вручную написал этот запрос (который работает) как
WITH `CTE_1` (`EmailAddress`)
AS
(
SELECT
`t1`.`email_address`
FROM
`emails` `t1`
GROUP BY
`t1`.`email_address`
HAVING
Count(*) > 1
)
UPDATE
`emails` `d`
INNER JOIN `CTE_1` `e` ON (`d`.`email_address` IS NULL AND `e`.`EmailAddress` IS NULL OR `d`.`email_address` = `e`.`EmailAddress`)
SET
`d`.`is_duplicate` = 1
Это ошибка с linq2db или я что-то упускаю?
Комментарии:
1. Это ошибка. Пожалуйста, создайте проблему в репозитории linq2db GitHub. Я знаю, что обновление с помощью CTE тестируется только на Sql Server.
2. Спасибо Святослав, сделаю. Тот же cte отлично работает для SELECT и генерирует оператор в правильном порядке.
3. Исправлено в linq2db 3.1.6