#sql #google-bigquery #sql-update #sql-merge
#sql #google-bigquery #sql-update #sql-merge
Вопрос:
Я хочу обновить целевую таблицу ( target
) в соответствии со строками в исходной таблице ( source
). Для этого я использую MERGE
инструкцию. Однако я хотел бы, чтобы вся MERGE
операция завершилась неудачей при некоторых условиях, но не могу понять, как это сделать.
Пример
target
Таблица содержит :
id
==
1
2
source
Таблица содержит :
id | operation
==============
3 | ADD
4 | DELETE
Ожидаемая target
таблица после MERGE
(я не хочу никаких обновлений здесь, потому что 4
соответствует DELETE
операции, и поскольку в 4
таблице нет target
строки, это рассматривается как ошибка и MERGE
должно завершиться атомарно) :
id
==
1
2
На данный момент я использую следующий запрос :
MERGE `target` target
USING `source` source
ON target.id = source.id
WHEN not matched AND source.operation = "ADD" THEN
INSERT (id)
VALUES (source.id)
Но, очевидно, я получил :
id
==
1
2
3
Возможно ли добавить в мой запрос предложение типа :
WHEN not matched AND source.operation = "DELETE" THEN ERROR("...")
Это не работает ( ERROR
неожиданно) :
Синтаксическая ошибка: Ожидалось удаление ключевого слова, или вставка ключевого слова, или обновление ключевого слова, но получен идентификатор «ОШИБКА»
Если это невозможно с помощью MERGE
запроса, есть ли способ переписать его в аналогичный запрос, чтобы атомарно обновить мою target
таблицу, как я ожидаю?
Ответ №1:
Вы могли бы сами сгенерировать ошибку. Что-то вроде:
WHEN not matched AND source.operation = 'DELETE' THEN
INSERT (id)
VALUES ( CAST(source.operation as int64) )
Я не пытался намеренно генерировать ошибки в BigQuery, но я не думаю, что существует функция, которая автоматически это делает.
По предложению @norbjd:
WHEN not matched AND source.operation = 'DELETE' THEN
INSERT (id)
VALUES ( ERROR('ERROR: DELETE operation encountered') )
Комментарии:
1. Спасибо за ваш ответ. Тип назначения в
CAST
не может бытьint
(недопустимый тип BigQuery), ноnumeric
,int64
или что-то другое допустимо; однако решение все еще применяется.2. В BigQuery существует
ERROR
функция для генерации ошибки ( cloud.google.com/bigquery/docs/reference/standard-sql /… ), но не может использоваться как есть, так как ожидается толькоDELETE
илиINSERT
послеWHEN ... THEN
. Но, основываясь на вашем решении, я мог бы написать :INSERT (id) VALUES (ERROR('Error message'))
чтобы получить более четкое сообщение, даже если это кажется взломом.