【问题标题】:How to append data to a JSON object during a select?如何在选择期间将数据附加到 JSON 对象?
【发布时间】:2019-02-14 21:11:08
【问题描述】:

我正在从旧系统迁移数据。我有一些布尔列,可以是TrueFalseNull。每一列都有一定的含义。在新数据库中,我使用 JSON Data 对象。我想要实现的是:

OldTable:
ValueA, ValueB, ValueC, ValueD
Null  , True  , False , True

我现在使用旧表上的选择和FOR JSON 创建 Json 数据以获取 Json 对象。该对象应如下所示:

{
     myObject: {
           data: "valueB, ValueD"
     }
}

我的问题是将值附加到相同的“数据”字段。

所以现在我只能使用这样的单个值:

SELECT CASE WHEN ValueA == True THEN 'ValueA' END 'myObject.data',
       CASE WHEN ValueB == True THEN 'ValueB' END 'myObject.data'  
FROM myLegacyTable FOR JSON Path

这显然会覆盖myObject.data 中的内容,只要两个值都为真。 JSON_MODIFY 似乎不是一个选项,因为我不是在处理现有的 Json 对象,而是创建一个新对象。也许其他人有想法?

【问题讨论】:

  • 您的预期结果不是有效的 json 表达式。您可能想要一个 json 数组:{ "myObject": { "data": ["valueB", "ValueD"] } }
  • 您好安德里亚,感谢您的评论。我更新我的帖子。我不想要一个 json 数组,而是一个 json 值,它是一个逗号分隔的列表。我用它来设置一个 .net 标志枚举。
  • == 不是有效的 T-SQL 语法,True 也不是。即使我们理解您的意思,当您发布功能代码时,整个事情会更好。 myLegacyTable 到底是什么?
  • JSON 是一种很好的消息格式,但不是存储关系数据的好选择。然后通过将多个属性填充到一个属性中来破坏 JSON 的规则,使情况变得更糟......无论如何,您的 JSON 中 data 的值只是一个字符串。因此,只需使用 select 语句在 one 列中生成整个字符串。不要将它放在单独的列中,因为您的 JSON 只引用一个字符串。
  • 当表格包含多于一行时,预期的输出是什么?

标签: sql json sql-server tsql database-migration


【解决方案1】:

您可以使用 CASE WHEN 构建您的 json 字符串。如果您想处理可变数量的列,您可能需要动态 TSQL。

这是一个简单的静态版本,应该可以完成这项工作:

declare @tmp table(ValueA bit, ValueB bit, ValueC bit, ValueD bit)
insert into @tmp values (null, 1 ,0 , 1)

SELECT JSON_QUERY('{"data":"' + 
stuff(
      case when ValueA = 1 then  ',ValueA'  else '' end 
    + case when ValueB = 1 then  ',ValueB'  else '' end 
    + case when ValueC = 1 then  ',ValueC'  else '' end 
    + case when ValueD = 1 then  ',ValueD'  else '' end 
    ,1,1,'') 
    + '"}') as myObject
FROM @tmp FOR JSON Path, without_array_wrapper

结果:

【讨论】:

  • 嗨@Andrea,那是票!非常感谢!
【解决方案2】:

我不知道你的源数据是如何真正存储的,但如果这一切都在 SQL Server 中,你需要做一个例子

data.property 不是单独的项目,因此不要将其拆分为列。它只是一个连接的字符串。因此,将所有内容连接起来并删除结尾的逗号。

DECLARE @MyTable TABLE (
RowID INT,
ValueA VARCHAR(5),
ValueB VARCHAR(5),
ValueC VARCHAR(5),
ValueD VARCHAR(5)
)

INSERT INTO @MyTable (RowID,ValueA,ValueB,ValueC,ValueD) VALUES 
(1,NULL,'True','False','True'),
(2,'False',NULL,'True','True'),
(3,NULL,'False',NULL,NULL)

SELECT 
ISNULL(
RTRIM(REVERSE(STUFF(REVERSE
(
CASE WHEN ValueA='True' THEN 'ValueA, ' ELSE '' END +
CASE WHEN ValueB='True' THEN 'ValueB, ' ELSE '' END +
CASE WHEN ValueC='True' THEN 'ValueC, ' ELSE '' END +
CASE WHEN ValueD='True' THEN 'ValueD, ' ELSE '' END
), 2, 1, ''))),'') AS 'myObject.data'
FROM @MyTable
FOR JSON Path

删除尾随 , 所需的巨大构造来自这里:

Remove the last character in a string in T-SQL?

结果:

[
    {
        "myObject": {
            "data": "ValueB, ValueD"
        }
    },
    {
        "myObject": {
            "data": "ValueC, ValueD"
        }
    },
    {
        "myObject": {
            "data": ""
        }
    }
]

【讨论】:

    猜你喜欢
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    • 1970-01-01
    • 1970-01-01
    • 2020-12-03
    • 1970-01-01
    相关资源
    最近更新 更多