【问题标题】:How to exclude multiple values from JSON String in MS SQL Stored Procedure如何从 MS SQL 存储过程中的 JSON 字符串中排除多个值
【发布时间】:2023-01-06 23:22:40
【问题描述】:

我有一个如下所示的 JSON 字符串:

{
  "Country": {
    "Layer4": [
      {
        "ItemName": "Cabinet MT",
        "ItemId": "cc3b0435-9ff5-4fd8-9f49-e049919a1414"
      },
      {
        "ItemName": "Other MT",
        "ItemId": "cc3b0435-9ff5-4fd8-9f49-e049919a1414"
      },
      {
        "ItemName": "Cold MT",
        "ItemId": "cc3b0435-9ff5-4fd8-9f49-e049919a1414"
      },
      {
        "ItemName": "Cold MT",
        "ItemId": "672f9a8c-71bb-4851-87de-e68154cabfad"
      },
      {
        "ItemName": "Cabinet MT",
        "ItemId": "672f9a8c-71bb-4851-87de-e68154cabfad"
      }
    ]
  },
  "CountryID": "b4283692-7c14-46da-9480-9a2976187316"
}

我想删除第 4 层下的数据,其 ItemName = 'Cabinet MT' and ItemName = 'Other MT' and ItemId = 'cc3b0435-9ff5-4fd8-9f49-e049919a1414' 最后我希望 JSON 字符串如下所示:

{
  "Country": {
    "Layer4": [
      {
        "ItemName": "Cold MT",
        "ItemId": "cc3b0435-9ff5-4fd8-9f49-e049919a1414"
      },
      {
        "ItemName": "Cold MT",
        "ItemId": "672f9a8c-71bb-4851-87de-e68154cabfad"
      },
      {
        "ItemName": "Cabinet MT",
        "ItemId": "672f9a8c-71bb-4851-87de-e68154cabfad"
      }
    ]
  },
  "CountryID": "b4283692-7c14-46da-9480-9a2976187316"
}

我试过以下格式:

Declare @Input NVARCHAR(MAX) = N'{"Country":{"Layer4":[{"ItemName":"Cabinet MT","ItemId":"cc3b0435-9ff5-4fd8-9f49-e049919a1414"},{"ItemName":"Other MT","ItemId":"cc3b0435-9ff5-4fd8-9f49-e049919a1414"},{"ItemName":"Cold MT","ItemId":"cc3b0435-9ff5-4fd8-9f49-e049919a1414"},{"ItemName":"Cold MT","ItemId":"672f9a8c-71bb-4851-87de-e68154cabfad"},{"ItemName":"Cabinet MT","ItemId":"672f9a8c-71bb-4851-87de-e68154cabfad"}]},"CountryID":"b4283692-7c14-46da-9480-9a2976187316"}';
DECLARE @JSONOutput AS NVARCHAR(MAX);
DECLARE @JSONData AS NVARCHAR(MAX);

SET @JSONData = @Input; 

            SELECT @JSONOutput = JSON_MODIFY(@JSONData, '$.Country.Layer4', JSON_QUERY('[]'))
            SELECT @JSONOutput = JSON_MODIFY(@JSONOutput, 'append $.Country.Layer4', JSON_QUERY(@JSONData, '$.Country.Layer4[' + [key] + ']'))
            FROM OPENJSON(@JSONData, '$.Country.Layer4')
            WHERE JSON_VALUE([value], '$.ItemName') NOT IN('Cabinet MT', 'Other MT')
            and JSON_VALUE([value], '$.ItemId') NOT IN ('cc3b0435-9ff5-4fd8-9f49-e049919a1414')

            Print @JSONOutput

我得到的输出是:

{
  "Country": {
    "Layer4": [
      {
        "ItemName": "Cold MT",
        "ItemId": "672f9a8c-71bb-4851-87de-e68154cabfad"
      }
    ]
  },
  "CountryID": "b4283692-7c14-46da-9480-9a2976187316"
}

有人可以帮我删除满足我条件的特定值吗

【问题讨论】:

  • 为什么你标记了两个 SQL ServerMySQL?您真正使用的是什么 RDBMS?当上面没有 C# 代码并且从未提及时,上面与 C# 有什么关系?存储过程也与该问题有什么关系?我已经基本上删除了这里的所有标签;请edit你的问题适当地(重新)标记事物。

标签: sql json


【解决方案1】:

这似乎是一个错误的布尔逻辑,尝试使用不同的 WHERE 子句:

...
WHERE NOT (
   (JSON_VALUE([value], '$.ItemName') = N'Other MT') AND (JSON_VALUE([value], '$.ItemId') = N'cc3b0435-9ff5-4fd8-9f49-e049919a1414') OR
   (JSON_VALUE([value], '$.ItemName') = N'Cabinet MT') AND (JSON_VALUE([value], '$.ItemId') = N'cc3b0435-9ff5-4fd8-9f49-e049919a1414')
)  

重要说明(如BOL 中所述):不要在 SELECT 语句中使用变量来连接值(即计算聚合值)。可能会出现意外的查询结果,因为 SELECT 列表中的所有表达式(包括赋值)不一定对每个输出行只运行一次。

一种可能的方法是解析、过滤和重建输入 JSON:

SELECT @JSONOutput = JSON_MODIFY (
   @Input,
   '$.Country.Layer4',
   (
   SELECT * 
   FROM OPENJSON(@Input, '$.Country.Layer4') WITH (
      ItemName nvarchar(100) '$.ItemName',
      ItemId nvarchar(36) '$.ItemId'
   )  
   WHERE NOT (
      (ItemName = N'Other MT') AND (ItemId = N'cc3b0435-9ff5-4fd8-9f49-e049919a1414') OR
      (ItemName = N'Cabinet MT') AND (ItemId = N'cc3b0435-9ff5-4fd8-9f49-e049919a1414')
   )  
   FOR JSON PATH
   )
)  

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-20
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    • 1970-01-01
    • 2014-03-29
    • 2014-10-20
    相关资源
    最近更新 更多