有没有办法参数化openjson的第二个参数
Is there a way to parameterize the second argument of openjson
我的 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'
。
请帮我实现同样的目标。地址的数量可能不同,所以我想让它动态化。
试试这个:
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;
只需将第二个参数构建为字符串并传递即可。
确切答案是是的,但这取决于SQL服务器版本。您有以下选项:
对于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。结果是包含 key
、value
和 type
.
列的 table
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
我的 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'
。
请帮我实现同样的目标。地址的数量可能不同,所以我想让它动态化。
试试这个:
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;
只需将第二个参数构建为字符串并传递即可。
确切答案是是的,但这取决于SQL服务器版本。您有以下选项:
对于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。结果是包含 key
、value
和 type
.
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