92 lines
3.7 KiB
MySQL
92 lines
3.7 KiB
MySQL
|
|
-- ============================================================================
|
|||
|
|
-- SQL запрос для обновления upload_description документа по claim_document_id
|
|||
|
|
-- ============================================================================
|
|||
|
|
-- Параметры:
|
|||
|
|
-- $1 :: uuid -- claim_document_id (ID документа из таблицы clpr_claim_documents)
|
|||
|
|
-- $2 :: text -- upload_description (новое описание документа)
|
|||
|
|
-- ============================================================================
|
|||
|
|
|
|||
|
|
WITH
|
|||
|
|
-- Находим документ и извлекаем нужные данные
|
|||
|
|
doc_info AS (
|
|||
|
|
SELECT
|
|||
|
|
cd.id AS claim_document_id,
|
|||
|
|
cd.claim_id::text AS claim_id_text,
|
|||
|
|
cd.field_name,
|
|||
|
|
-- Извлекаем индекс i из field_name (например, uploads[0][0] -> 0)
|
|||
|
|
NULLIF((regexp_match(cd.field_name, 'uploads\[(\d+)\]'))[1], '')::int AS upload_index,
|
|||
|
|
c.id AS claim_uuid,
|
|||
|
|
c.payload
|
|||
|
|
FROM clpr_claim_documents cd
|
|||
|
|
JOIN clpr_claims c ON c.id::text = cd.claim_id::text
|
|||
|
|
WHERE cd.id = $1
|
|||
|
|
LIMIT 1
|
|||
|
|
),
|
|||
|
|
|
|||
|
|
-- Обновляем payload: приоритет обновления в следующем порядке:
|
|||
|
|
-- 1. payload.body['uploads_descriptions[i]'] (самый приоритетный)
|
|||
|
|
-- 2. payload['uploads_descriptions[i]'] (если нет body)
|
|||
|
|
-- 3. payload.edit_fields_parsed.uploads_descriptions[i] (массив, если нет плоских ключей)
|
|||
|
|
updated_claim AS (
|
|||
|
|
UPDATE clpr_claims c
|
|||
|
|
SET
|
|||
|
|
payload = CASE
|
|||
|
|
-- Если есть payload.body, обновляем там
|
|||
|
|
WHEN c.payload->'body' IS NOT NULL THEN
|
|||
|
|
jsonb_set(
|
|||
|
|
c.payload,
|
|||
|
|
ARRAY['body', 'uploads_descriptions[' || di.upload_index::text || ']'],
|
|||
|
|
to_jsonb($2::text),
|
|||
|
|
true
|
|||
|
|
)
|
|||
|
|
-- Если нет body, но есть корневой ключ, обновляем там
|
|||
|
|
WHEN c.payload ? ('uploads_descriptions[' || di.upload_index::text || ']') THEN
|
|||
|
|
jsonb_set(
|
|||
|
|
c.payload,
|
|||
|
|
ARRAY['uploads_descriptions[' || di.upload_index::text || ']'],
|
|||
|
|
to_jsonb($2::text),
|
|||
|
|
true
|
|||
|
|
)
|
|||
|
|
-- Если есть edit_fields_parsed.uploads_descriptions (массив), обновляем там
|
|||
|
|
WHEN c.payload->'edit_fields_parsed'->'uploads_descriptions' IS NOT NULL
|
|||
|
|
AND jsonb_typeof(c.payload->'edit_fields_parsed'->'uploads_descriptions') = 'array' THEN
|
|||
|
|
-- Для массива используем jsonb_set с числовым индексом
|
|||
|
|
jsonb_set(
|
|||
|
|
c.payload,
|
|||
|
|
ARRAY['edit_fields_parsed', 'uploads_descriptions', di.upload_index::text],
|
|||
|
|
to_jsonb($2::text),
|
|||
|
|
true
|
|||
|
|
)
|
|||
|
|
-- Если ничего нет, создаём в body
|
|||
|
|
ELSE
|
|||
|
|
jsonb_set(
|
|||
|
|
COALESCE(c.payload, '{}'::jsonb),
|
|||
|
|
ARRAY['body', 'uploads_descriptions[' || di.upload_index::text || ']'],
|
|||
|
|
to_jsonb($2::text),
|
|||
|
|
true
|
|||
|
|
)
|
|||
|
|
END,
|
|||
|
|
updated_at = now()
|
|||
|
|
FROM doc_info di
|
|||
|
|
WHERE c.id = di.claim_uuid
|
|||
|
|
RETURNING c.id, c.payload
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
-- Возвращаем обновлённые данные
|
|||
|
|
SELECT
|
|||
|
|
di.claim_document_id,
|
|||
|
|
di.claim_id_text AS claim_id,
|
|||
|
|
di.field_name,
|
|||
|
|
di.upload_index,
|
|||
|
|
-- Проверяем, где сохранилось описание
|
|||
|
|
COALESCE(
|
|||
|
|
uc.payload->'body'->>('uploads_descriptions[' || di.upload_index::text || ']'),
|
|||
|
|
uc.payload->>('uploads_descriptions[' || di.upload_index::text || ']'),
|
|||
|
|
uc.payload->'edit_fields_parsed'->'uploads_descriptions'->>di.upload_index::text,
|
|||
|
|
NULL
|
|||
|
|
) AS upload_description,
|
|||
|
|
uc.payload
|
|||
|
|
FROM doc_info di
|
|||
|
|
JOIN updated_claim uc ON uc.id = di.claim_uuid;
|
|||
|
|
|