如何在查询SQL中将json值用作列?

时间:2019-10-03 16:53:07

标签: json sql-server

我只想接收json数据并将其字段用作其他查询的表列。

我试图将键“ nameProperty”中的值放入表的一列中,并将键“ newValue”的值填充到该列的行中。

例如:

我得到这样的json文件

var mystring = "this|is|a|test";
mystring = mystring.replace(/\|/g, "");
alert(mystring);

我想提取“字段”列表中的对象,但是我只能将它们作为键行,而将另一行作为值,如下面的脚本所示。

{ 
   "operation":{ 
      "ID":"ABC",
      "KinshipDescription":"--"
   },
   "fields":[ 
      { 
         "property":{ 
            "nameProperty":"ID",
            "oldValue":"",
            "newValue":"123456",
            "confirmed":"false",
            "labelProperty":"ID",
            "oldValueDescription":"",
            "newValueDescription":"123456"
         }
      },
      { 
         "property":{ 
            "nameProperty":"Name",
            "oldValue":"",
            "newValue":"John",
            "confirmed":"false",
            "labelProperty":"Name",
            "oldValueDescription":"",
            "newValueDescription":"John"
         }
      }
   ]
}

我不知道该怎么做

这个脚本的结果是这样的

DECLARE @jsonObj NVARCHAR(MAX)
--Set a result in 
SET @jsonObj = (select JSON_Query(data, '$.fields') from table where id = 'ABC')

select * from openjson(@jsonObj) 
with (Property nvarchar(255) '$.property.nameProperty',
 newValue nvarchar(50) '$.property.newValue') 

我想看的结果是

ID  123456
Name    John

1 个答案:

答案 0 :(得分:2)

为此我能想到的最快的方法(考虑性能,不一定是性能)是使用动态SQL。实际上,我确定您必须使用它。

这是一个可以使您感动的示例。您可以在SSMS中运行它。

DECLARE @json NVARCHAR(MAX) =
'{ 
   "operation":{ 
      "ID":"ABC",
      "KinshipDescription":"--"
   },
   "fields":[ 
      { 
         "property":{ 
            "nameProperty":"ID",
            "oldValue":"",
            "newValue":"123456",
            "confirmed":"false",
            "labelProperty":"ID",
            "oldValueDescription":"",
            "newValueDescription":"123456"
         }
      },
      { 
         "property":{ 
            "nameProperty":"Name",
            "oldValue":"",
            "newValue":"John",
            "confirmed":"false",
            "labelProperty":"Name",
            "oldValueDescription":"",
            "newValueDescription":"John"
         }
      }
   ]
}';

-- Variable to hold the column/values.
DECLARE @cols VARCHAR(MAX) = '';

-- Generate the column/value pairs.
SELECT 
    @cols = @cols
        + CASE WHEN ( LEN( @cols ) > 0 ) THEN ', ' ELSE '' END -- add comma if needed.
        + '''' + Properties.newValue + ''' AS [' + Properties.nameProperty + '] '
FROM OPENJSON( @json, '$.fields' ) WITH (
    property NVARCHAR(MAX) '$.property' AS JSON
)
CROSS APPLY (

    SELECT * FROM OPENJSON( property ) WITH (
        nameProperty VARCHAR(50) '$.nameProperty',
        oldValue     VARCHAR(50) '$.oldValue',
        newValue     VARCHAR(50) '$.newValue',
        confirmed    VARCHAR(50) '$.confirmed',
        labelProperty VARCHAR(50) '$.labelProperty',
        oldValueDescription VARCHAR(50) '$.oldValueDescription',
        newValueDescription VARCHAR(50) '$.newValueDescription'
    )

) AS Properties;

-- Execute column/value pairs as dynamic SQL.
EXEC ( 'SELECT ' + @cols );

哪个返回:

+--------+------+
|   ID   | Name |
+--------+------+
| 123456 | John |
+--------+------+

如果您要打印@cols,将会看到

'123456' AS [ID] , 'John' AS [Name] 

一些简短说明:

  • 性能可能会有所不同。
  • 带引号的值,但需要时可以 CAST
  • 例如,在交叉申请中包括了所有“属性”字段。仅指定需要的内容。
  • 注意在使用AS JSON
  • 时使用 NVARCHAR
  • 如果不存在“属性”,则可能要考虑外部申请