有没有一种方法可以参数化openjson

时间:2020-04-21 09:13:52

标签: sql json sql-server tsql jsonparser

我的json数据如下:

SET @json='{
    "_id": "4erutit8979044kd5",
    "ADDRESSES": {
        "1": {
            "VALIDATED": "",
            "TYPE": "billing",
            "RESIDENTIAL": "",
            "REGION": "ON",
            "POSTAL": "L6789W",
            "PO": 0,
            "PHONE": "222222",
            "NAME_2": "Kapil",
            "NAME_1": "Kaushal",
            "LINE_2": "",
            "LINE_1": "215 Wards Ct.",
            "EMAIL": "kapilk@gmail.com",
            "COUNTRY": "IN",
            "CITY": "Jodhpur",
            "LAST_USED": 1435590000.0
        },
        "2": {
            "TYPE": "billing",
            "RESIDENTIAL": "",
            "REGION": "JD",
            "POSTAL": "2222",
            "PO": 0,
            "PHONE": "",
            "NAME_2": "Salman",
            "NAME_1": "Kursheed",
            "LINE_2": "",
            "LINE_1": "1459 Thomas Street",
            "EMAIL": "salmank@gmail.com",
            "COUNTRY": "IN",
            "CITY": "Jodhpur",
            "LAST_USED": 1436460000.0,
            "VALIDATED": "dirty"
        },
        "3": {
            "VALIDATED": "clean",
            "TYPE": "shipping",
            "CITY": "Jaisalmer",
            "COUNTRY": "IN",
            "EMAIL": "rajk@gmail.com",
            "LINE_1": "1020 Carripa Enclave",
            "LINE_2": "",
            "NAME_1": "Raj",
            "NAME_2": "Kumar",
            "PO": 0,
            "POSTAL": "222234",
            "REGION": "JS",
            "LAST_VALIDATED": "2015-07-14T16:20:42.242Z",
            "LAST_USED": 1436460000.0
        }
    }, ...
and so on

我想实现以下目标:

WHILE @cnt < 3
BEGIN
   --insert into dummy_table
   select *   
   from   openjson (@json,'$.ADDRESSES."@cnt"')
   SET @cnt = @cnt + 1;
END;

该行工作正常,如下:

select *   from   openjson (@json,'$.ADDRESSES."1"')
select *   from   openjson (@json,'$.ADDRESSES."1"')

但是即使我将@cnt定义为@cnt,也不能使用变量char = '1'

请帮助我实现相同目标。地址的数量可能会有所不同,所以我想使其动态化。

2 个答案:

答案 0 :(得分:1)

尝试一下:

DECLARE @json NVARCHAR(MAX);

SET @json='{
    "_id": "4erutit8979044kd5",
    "ADDRESSES": {
        "1": {
            "VALIDATED": "",
            "TYPE": "billing",
            "RESIDENTIAL": "",
            "REGION": "ON",
            "POSTAL": "L6789W",
            "PO": 0,
            "PHONE": "222222",
            "NAME_2": "Kapil",
            "NAME_1": "Kaushal",
            "LINE_2": "",
            "LINE_1": "215 Wards Ct.",
            "EMAIL": "kapilk@gmail.com",
            "COUNTRY": "IN",
            "CITY": "Jodhpur",
            "LAST_USED": 1435590000.0
        },
        "2": {
            "TYPE": "billing",
            "RESIDENTIAL": "",
            "REGION": "JD",
            "POSTAL": "2222",
            "PO": 0,
            "PHONE": "",
            "NAME_2": "Salman",
            "NAME_1": "Kursheed",
            "LINE_2": "",
            "LINE_1": "1459 Thomas Street",
            "EMAIL": "salmank@gmail.com",
            "COUNTRY": "IN",
            "CITY": "Jodhpur",
            "LAST_USED": 1436460000.0,
            "VALIDATED": "dirty"
        },
        "3": {
            "VALIDATED": "clean",
            "TYPE": "shipping",
            "CITY": "Jaisalmer",
            "COUNTRY": "IN",
            "EMAIL": "rajk@gmail.com",
            "LINE_1": "1020 Carripa Enclave",
            "LINE_2": "",
            "NAME_1": "Raj",
            "NAME_2": "Kumar",
            "PO": 0,
            "POSTAL": "222234",
            "REGION": "JS",
            "LAST_VALIDATED": "2015-07-14T16:20:42.242Z",
            "LAST_USED": 1436460000.0
        }
    }'


DECLARE @cnt INT = 1;
DECLARE @query NVARCHAR(128);

WHILE @cnt <= 3
BEGIN
--insert into dummy_table

SET @query = '$.ADDRESSES."' + CAST(@cnt AS VARCHAR(4)) + '"'

select *   
from   openjson (@json,@query)
SET @cnt = @cnt + 1;
END;

只需将第二个参数构建为字符串并将其传递。

答案 1 :(得分:1)

确切答案是是,但这取决于SQL Server版本。您有以下选择:

对于SQL Server 2017+,可以提供变量作为值path。请注意,当键名以美元符号开头或包含特殊字符(例如空格或数字)时,您需要在其周围加上引号。

DECLARE @cnt int
SET @cnt = 1

--INSERT INTO dummy_table
SELECT *
FROM OPENJSON(@json, CONCAT('$.ADDRESSES."', @cnt, '"'))

对于SQL Server 2016+,您需要使用OPENJSON()和默认架构来解析输入的JSON。结果是一个包含列keyvaluetype的表。

DECLARE @cnt int
SET @cnt = 1

--INSERT INTO dummy_table
SELECT j2.*
FROM OPENJSON(@json, '$.ADDRESSES') j1
CROSS APPLY OPENJSON(j1.[value]) j2
WHERE j1.[key] = @cnt

结果:

key        value         type
VALIDATED                   1
TYPE       billing          1
RESIDENTIAL                 1
REGION     ON               1
POSTAL     L6789W           1
PO         0                2
PHONE      222222           1
NAME_2     Kapil            1
NAME_1     Kaushal          1
LINE_2                      1
LINE_1     215 Wards Ct.    1
EMAIL      kapilk@gmail.com 1
COUNTRY    IN               1
CITY       Jodhpur          1
LAST_USED  1435590000.0     2

作为附加选项,您不需要WHILE循环即可从输入JSON获取特定值。以下语句分析来自$.ADDRESSES.1$.ADDRESSES.2$.ADDRESSES.3键的值。

--INSERT INTO dummy_table
SELECT j2.*
FROM (VALUES (1), (2), (3)) v(cnt)
JOIN OPENJSON(@json, '$.ADDRESSES') j1 ON CONVERT(int, j1.[key]) = v.cnt
CROSS APPLY OPENJSON(j1.[value]) j2