mysql - 将所有多行 LONGTEXT 列转换为 JSON 列

标签 mysql sql json type-conversion

总结: 进行数据库迁移时,我正在尝试将值(value) 10k 的 LONGTEXT COLUMNS 中充满带有换行符的段落移动到 JSON 数据类型的新 DB TABLE COLUMN 中。

规范: MYSQL v5.7 和使用 InnoDB 引擎(因此对 JSON 功能有一些限制。)

示例表 OLD_DB_TABtext_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_TABjson_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 转换为 NEW_DB.json_text_body 中的 JSON 数据类型。有SQL代码解决方案吗?

最佳答案

我可以给你一个开始,将段落放入自己的行中,然后我构建一个 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;

你得到这个结果

[{"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 暂时不起作用。

Here is the whole thing at dbfiddle to play with

关于mysql - 将所有多行 LONGTEXT 列转换为 JSON 列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58018891/

相关文章:

sql - 如何给数据库约束以确保表中的这种行为?

MySQL:按类别计数项目

java - 返回嵌套在 mongo 文档中的随机元素

MySQL一对多连接?

asp.net - 防止SQL注入(inject)攻击: the differences between mySql and SQL Server 2008

mysql - SQL更新忽略重复项

javascript - 不用 Jquery 获取远程 JSON?

c# - 如何使用 Json.NET 将 IHtmlString 序列化为 JSON?

mysql - 仅检索类型为 're' 而不是 'res' 的行

PHP/MySQL - 计算查询中的项目数