Преобразовать все многострочные столбцы LONGTEXT в столбцы JSON - PullRequest
2 голосов
/ 20 сентября 2019

РЕЗЮМЕ: Выполняется миграция базы данных, и я пытаюсь переместить LONGTEXT COLUMNS на 10 тыс., Полный абзацев с разрывами строк, в новый тип DB TABLE COLUMN JSON.

SPECS: MYSQL v5.7 и использование InnoDB Engine (поэтому существуют некоторые ограничения для функциональности JSON.)

ПРИМЕРНАЯ ТАБЛИЦА OLD_DB_TAB COLUMN text_body:

ID     text_body 
1      This is an intro paragraph. Here are some words.

       And a second paragraph. More words.

2      This is another column value with multiline strings. Here are some 
       words.

       Look, another paragraph in this same column. More words. 
       Even a third paragraph!

3      And so on ...

ПРИМЕР ТАБЛИЦЫ NEW_DB_TAB КОЛОНКА json_text_body:

ID     json_text_body 
1      {"body": [{"insert": "This is an intro paragraph. Here are some 
       words.\nAnd a second paragraph. More words.\n\n"}]}

2      {"body": [{"insert": "This is another column value with multiline 
       strings.\nHere are some words.\nLook, another paragraph in this 
       same column.\nMore words.\nEven a third paragraph!\n\n"}]}

3      {"body": [{"insert": "And so on ...\n\n"}]}

Моя последняя попытка решения кода SQL не удалась, и ошибка говорит: «Подзапрос возвращает более 1 строки»:

SELECT CAST((SELECT `text_body` FROM `OLD_DB`) AS JSON)

Как я могу: Преобразовать все столбцы LONGTEXT в столбцы JSON?В приведенных здесь примерах таблиц преобразуйте OLD_DB.text_body в тип данных JSON в NEW_DB.json_text_body.Есть ли решение кода SQL?

1 Ответ

1 голос
/ 20 сентября 2019

Я могу дать вам начало, где абзацы помещаются в собственные строки, а затем я строю набор json.Конечно, вы должны изменить его, чтобы он соответствовал вашим данным

Итак, давайте начнем с этой базы данных в качестве базы

CREATE TABLE table1
    (`ID` int, `text_body` text)
;

INSERT INTO table1
    (`ID`, `text_body`)
VALUES
    (1, 'This is an intro paragraph. Here are some words.\n\nAnd a second paragraph. More words.'),
    (2, 'This is another column value with multiline strings. Here are some words.'),
    (3, 'Look, another paragraph in this same column. More words.\nEven a third paragraph!\nAnd so on ...')

;

Вы получаете с этим оператором Select

Select
JSON_ARRAYAGG(JSON_OBJECT("text_body", `part`,"ID",`ID` )) text_body
FROM
(
SELECT
  SUBSTRING_INDEX(
    SUBSTRING_INDEX(p.text_body, '\n', N.n + 1)
    , '\n', -1
   ) AS part
   ,p.ID
FROM (SELECT @n := @n + 1 AS n
   FROM INFORMATION_SCHEMA.COLUMNS AS a
   CROSS JOIN INFORMATION_SCHEMA.COLUMNS AS b
   CROSS JOIN (SELECT @n := -1) AS I
   WHERE @n < 1000) N 
  CROSS JOIN  table1 p
    WHERE 
      N.n <= (LENGTH(p.text_body) - LENGTH(REPLACE(p.text_body, '\n', ''))) 
)t1;

Youполучить этот результат

[{"ID": 1, "text_body": "This is an intro paragraph. Here are some words."},
 {"ID": 2, "text_body": "This is another column value with multiline strings. Here are some words."},
  {"ID": 3, "text_body": "Look, another paragraph in this same column. More words."},
  {"ID": 1, "text_body": "And a second paragraph. More words."},
  {"ID": 3, "text_body": "Even a third paragraph!"}
   , {"ID": 3, "text_body": "And so on ..."}]

Так что это работает с mysql 5,7 band 8.x, до этого не было функций json, которые могли бы это сделать, и вам нужно собрать его вручную с помощью concat.Но внутренний Select работает почти идеально, как и сейчас, только \ n \ n пока не работает.

Вот что на dbfiddle можно поиграть с

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...