SQL Server 2016 JSON 在现有列中
SQL Server 2016 JSON in existing column
我一直在用头撞墙,因为这可能是相当明显的事情,但是谷歌搜索没有给我提供答案,也没有提示我需要。希望这里的高手能帮帮我:)
我有一个 table 看起来有点像这样:
JSON已经在我的SQL服务器table里了,基本上就是一个篮子里的商品内容。当前行是整个购买的交易,JSON 是每个产品及其各种属性的另一个子集。
这里以JSON字符串的2行为例:
[{"id":"429ac4e546-11e6-471e","product_id":"dc85bff3ecb24","register_id":"0adaaf5c4a65e37c7","sequence":"0","handle":"Skirts","sku":"20052","name":"Skirts","quantity":1,"price":5,"cost":0,"price_set":1,"discount":-5,"loyalty_value":0.2,"tax":0,"tax_id":"dc85058a-a69e-11e58394d","tax_name":"No Tax","tax_rate":0,"tax_total":0,"price_total":5,"display_retail_price_tax_inclusive":"1","status":"CONFIRMED","attributes":[{"name":"line_note","value":""}]}]
和
[{"id":"09237884-9713-9b6751fe0b85ffd","product_id":"dc85058a-a66b4c06702e13","register_id":"06bf5b9-31e2b4ac9d0a","sequence":"0","handle":"BricaBrac","sku":"20076","name":"Bric a Brac","quantity":1,"price":7,"cost":0,"price_set":1,"discount":-7,"loyalty_value":0.28,"tax":0,"tax_id":"dc85058a-2-54f20388394d","tax_name":"No Tax","tax_rate":0,"tax_total":0,"price_total":7,"display_retail_price_tax_inclusive":"1","status":"CONFIRMED","attributes":[{"name":"line_note","value":""}]},{"id":"09237884-9713-9b601235370","product_id":"dc85058a-a6fe112-6b4bfafb107e","register_id":"06bf537bf6b9-31e2b4ac9d0a","sequence":"1","handle":"LadiesTops","sku":"20040","name":"Ladies Tops","quantity":1,"price":10,"cost":0,"price_set":1,"discount":-10,"loyalty_value":0.4,"tax":0,"tax_id":"dc85058a-a690388394d","tax_name":"No Tax","tax_rate":0,"tax_total":0,"price_total":10,"display_retail_price_tax_inclusive":"1","status":"CONFIRMED","attributes":[{"name":"line_note","value":""}]},{"id":"09237884-9713-9b52007fa6c7d","product_id":"dc85058a-a6fa-b4c06d7ed5a","register_id":"06bf537b-cf6b9-31e2b4ac9d0a","sequence":"2","handle":"DVD","sku":"20077","name":"DVD","quantity":1,"price":3,"cost":0,"price_set":1,"discount":-3,"loyalty_value":0.12,"tax":0,"tax_id":"dc85058a-e5-e112-54f20388394d","tax_name":"No Tax","tax_rate":0,"tax_total":0,"price_total":3,"display_retail_price_tax_inclusive":"1","status":"CONFIRMED","attributes":[{"name":"line_note","value":""}]}]
所以我想要实现的是从该列中的数据创建一个新的 table。 (然后我可以通过 id 字段中的唯一字符串将产品 table 加入到第一个 table 中)。
是否可以使用 sql2016.
中的新本机 JSON 执行此操作
我的替代方法是通过 SSIS 使用插件来完成它,但如果我可以使用 SQL 服务器本身内部的存储过程来完成它会更干净。
提前致谢!
这是使用 OPENJSON
从 JSON
中提取 ID
的一种方法
SELECT id
FROM Yourtable
CROSS apply Openjson([register_sale_products])
WITH (id varchar(500) 'lax $.id')
OPENJSON
有两种路径模式
- 斯特里克
- 宽松
Strict
: 当 property
在 path
中 not found 时会抛出错误
lax
: 这将 return NULL
当 property
未找到 在 path
中。如果你没有提到任何 模式 那么 Lax
将默认使用
您可以根据需要使用以上模式
演示版:
架构设置
CREATE TABLE json_test
(
json_col VARCHAR(8000)
)
示例数据
INSERT INTO json_test
VALUES ('[{"id":"429ac4e546-11e6-471e","product_id":"dc85bff3ecb24","register_id":"0adaaf5c4a65e37c7","sequence":"0","handle":"Skirts","sku":"20052","name":"Skirts","quantity":1,"price":5,"cost":0,"price_set":1,"discount":-5,"loyalty_value":0.2,"tax":0,"tax_id":"dc85058a-a69e-11e58394d","tax_name":"No Tax","tax_rate":0,"tax_total":0,"price_total":5,"display_retail_price_tax_inclusive":"1","status":"CONFIRMED","attributes":[{"name":"line_note","value":""}]}]'),
('[{"id":"09237884-9713-9b6751fe0b85ffd","product_id":"dc85058a-a66b4c06702e13","register_id":"06bf5b9-31e2b4ac9d0a","sequence":"0","handle":"BricaBrac","sku":"20076","name":"Bric a Brac","quantity":1,"price":7,"cost":0,"price_set":1,"discount":-7,"loyalty_value":0.28,"tax":0,"tax_id":"dc85058a-2-54f20388394d","tax_name":"No Tax","tax_rate":0,"tax_total":0,"price_total":7,"display_retail_price_tax_inclusive":"1","status":"CONFIRMED","attributes":[{"name":"line_note","value":""}]},{"id":"09237884-9713-9b601235370","product_id":"dc85058a-a6fe112-6b4bfafb107e","register_id":"06bf537bf6b9-31e2b4ac9d0a","sequence":"1","handle":"LadiesTops","sku":"20040","name":"Ladies Tops","quantity":1,"price":10,"cost":0,"price_set":1,"discount":-10,"loyalty_value":0.4,"tax":0,"tax_id":"dc85058a-a690388394d","tax_name":"No Tax","tax_rate":0,"tax_total":0,"price_total":10,"display_retail_price_tax_inclusive":"1","status":"CONFIRMED","attributes":[{"name":"line_note","value":""}]},{"id":"09237884-9713-9b52007fa6c7d","product_id":"dc85058a-a6fa-b4c06d7ed5a","register_id":"06bf537b-cf6b9-31e2b4ac9d0a","sequence":"2","handle":"DVD","sku":"20077","name":"DVD","quantity":1,"price":3,"cost":0,"price_set":1,"discount":-3,"loyalty_value":0.12,"tax":0,"tax_id":"dc85058a-e5-e112-54f20388394d","tax_name":"No Tax","tax_rate":0,"tax_total":0,"price_total":3,"display_retail_price_tax_inclusive":"1","status":"CONFIRMED","attributes":[{"name":"line_note","value":""}]}]')
查询
SELECT id
FROM json_test
CROSS apply Openjson(json_col)
WITH (id varchar(500) 'lax $.id')
结果:
╔═══════════════════════════════╗
║ id ║
╠═══════════════════════════════╣
║ 429ac4e546-11e6-471e ║
║ 09237884-9713-9b6751fe0b85ffd ║
║ 09237884-9713-9b601235370 ║
║ 09237884-9713-9b52007fa6c7d ║
║ 429ac4e546-11e6-471e ║
║ 09237884-9713-9b6751fe0b85ffd ║
║ 09237884-9713-9b601235370 ║
║ 09237884-9713-9b52007fa6c7d ║
╚═══════════════════════════════╝
感谢 Prdp 的回复,引导我找到答案,如下所示。
SELECT a.ID, b.* -- select ID from original table for proofing, and all from table b
FROM reporttest a -- table name with alias
CROSS apply Openjson([register_sale_products]) -- column name
WITH (
id nvarchar(200) '$.id',
product_id nvarchar(200) '$.product_id',
register_id nvarchar(200) '$.register_id',
sequence nvarchar(200) '$.sequence',
handle nvarchar(200) '$.handle',
sku nvarchar(200) '$.sku',
name nvarchar(200) '$.name',
quantity nvarchar(200) '$.quantity',
price nvarchar(200) '$.price',
cost nvarchar(200) '$.cost',
price_set nvarchar(200) '$.price_set',
discount nvarchar(200) '$.discount',
loyalty_value nvarchar(200) '$.loyalty_value',
tax nvarchar(200) '$.tax',
tax_id nvarchar(200) '$.tax_id',
tax_name nvarchar(200) '$.tax_name',
--No Tax nvarchar(200) '$.No Tax',
tax_rate nvarchar(200) '$.tax_rate',
tax_total nvarchar(200) '$.tax_total',
price_total nvarchar(200) '$.price_total',
display_retail_price_tax_inclusive nvarchar(200) '$.display_retail_price_tax_inclusive',
status nvarchar(200) '$.status',
CONFIRMED nvarchar(200) '$.CONFIRMED',
attributes nvarchar(200) '$.attributes',
name nvarchar(200) '$.name',
line_note nvarchar(200) '$.line_note',
value nvarchar(200) '$.value'
) b -- alias the "with" section as table b
通过简单的 sql 查询不费吹灰之力,您将到达目的地。
make this query as stored procedure and call it when needed..
根据您的要求编辑此查询。
将“%id”:“”更改为“%anything_inside_the_string”,您将获得值..:)
DECLARE @LOOP_1 INT=1,@NAME NVARCHAR (MAX),@LEFT NVARCHAR(MAX),@loop_2 int=0
SET @NAME='[{"id":"429ac4e546-11e6-471e","product_id":"dc85bff3ecb24","register_id":"0adaaf5c4a65e37c7","sequence":"0","handle":"Skirts","sku":"20052","name":"Skirts","quantity":1,"price":5,"cost":0,"price_set":1,"discount":-5,"loyalty_value":0.2,"tax":0,"tax_id":"dc85058a-a69e-11e58394d","tax_name":"No Tax","tax_rate":0,"tax_total":0,"price_total":5,"display_retail_price_tax_inclusive":"1","status":"CONFIRMED","attributes":[{"name":"line_note","value":""}]}]'
-- First loop started to find where 'id":"' is located
WHILE @LOOP_1!=(SELECT LEN(@NAME))
BEGIN
SET @LEFT=(LEFT(@NAME,@LOOP_1))
IF @LEFT LIKE '%id":"' -------- Change '%id":"' to '%product_id":"' and you will get the value.. :)
BEGIN
set @NAME=(right(@NAME,len(@name)-@LOOP_1))
-- Second loop started to find where ',' is located after '"id":"'
WHILE @loop_2!=(SELECT LEN(@NAME))
BEGIN
SET @LEFT=(LEFT(@NAME,@loop_2))
IF @LEFT LIKE '%,'
BEGIN
if left(@name,@loop_2-1)like '%"%'
SELECT left(@name,@loop_2-2)
else
SELECT left(@name,@loop_2-2)
set @loop_2=(SELECT LEN(@NAME)-1)
set @loop_1=@loop_2
END
SET @loop_2=@loop_2+1
END
END
SET @LOOP_1=@LOOP_1+1
END
我一直在用头撞墙,因为这可能是相当明显的事情,但是谷歌搜索没有给我提供答案,也没有提示我需要。希望这里的高手能帮帮我:)
我有一个 table 看起来有点像这样:
这里以JSON字符串的2行为例:
[{"id":"429ac4e546-11e6-471e","product_id":"dc85bff3ecb24","register_id":"0adaaf5c4a65e37c7","sequence":"0","handle":"Skirts","sku":"20052","name":"Skirts","quantity":1,"price":5,"cost":0,"price_set":1,"discount":-5,"loyalty_value":0.2,"tax":0,"tax_id":"dc85058a-a69e-11e58394d","tax_name":"No Tax","tax_rate":0,"tax_total":0,"price_total":5,"display_retail_price_tax_inclusive":"1","status":"CONFIRMED","attributes":[{"name":"line_note","value":""}]}]
和
[{"id":"09237884-9713-9b6751fe0b85ffd","product_id":"dc85058a-a66b4c06702e13","register_id":"06bf5b9-31e2b4ac9d0a","sequence":"0","handle":"BricaBrac","sku":"20076","name":"Bric a Brac","quantity":1,"price":7,"cost":0,"price_set":1,"discount":-7,"loyalty_value":0.28,"tax":0,"tax_id":"dc85058a-2-54f20388394d","tax_name":"No Tax","tax_rate":0,"tax_total":0,"price_total":7,"display_retail_price_tax_inclusive":"1","status":"CONFIRMED","attributes":[{"name":"line_note","value":""}]},{"id":"09237884-9713-9b601235370","product_id":"dc85058a-a6fe112-6b4bfafb107e","register_id":"06bf537bf6b9-31e2b4ac9d0a","sequence":"1","handle":"LadiesTops","sku":"20040","name":"Ladies Tops","quantity":1,"price":10,"cost":0,"price_set":1,"discount":-10,"loyalty_value":0.4,"tax":0,"tax_id":"dc85058a-a690388394d","tax_name":"No Tax","tax_rate":0,"tax_total":0,"price_total":10,"display_retail_price_tax_inclusive":"1","status":"CONFIRMED","attributes":[{"name":"line_note","value":""}]},{"id":"09237884-9713-9b52007fa6c7d","product_id":"dc85058a-a6fa-b4c06d7ed5a","register_id":"06bf537b-cf6b9-31e2b4ac9d0a","sequence":"2","handle":"DVD","sku":"20077","name":"DVD","quantity":1,"price":3,"cost":0,"price_set":1,"discount":-3,"loyalty_value":0.12,"tax":0,"tax_id":"dc85058a-e5-e112-54f20388394d","tax_name":"No Tax","tax_rate":0,"tax_total":0,"price_total":3,"display_retail_price_tax_inclusive":"1","status":"CONFIRMED","attributes":[{"name":"line_note","value":""}]}]
所以我想要实现的是从该列中的数据创建一个新的 table。 (然后我可以通过 id 字段中的唯一字符串将产品 table 加入到第一个 table 中)。
是否可以使用 sql2016.
中的新本机 JSON 执行此操作我的替代方法是通过 SSIS 使用插件来完成它,但如果我可以使用 SQL 服务器本身内部的存储过程来完成它会更干净。
提前致谢!
这是使用 OPENJSON
从 JSON
ID
的一种方法
SELECT id
FROM Yourtable
CROSS apply Openjson([register_sale_products])
WITH (id varchar(500) 'lax $.id')
OPENJSON
有两种路径模式
- 斯特里克
- 宽松
Strict
: 当 property
在 path
lax
: 这将 return NULL
当 property
未找到 在 path
中。如果你没有提到任何 模式 那么 Lax
将默认使用
您可以根据需要使用以上模式
演示版:
架构设置
CREATE TABLE json_test
(
json_col VARCHAR(8000)
)
示例数据
INSERT INTO json_test
VALUES ('[{"id":"429ac4e546-11e6-471e","product_id":"dc85bff3ecb24","register_id":"0adaaf5c4a65e37c7","sequence":"0","handle":"Skirts","sku":"20052","name":"Skirts","quantity":1,"price":5,"cost":0,"price_set":1,"discount":-5,"loyalty_value":0.2,"tax":0,"tax_id":"dc85058a-a69e-11e58394d","tax_name":"No Tax","tax_rate":0,"tax_total":0,"price_total":5,"display_retail_price_tax_inclusive":"1","status":"CONFIRMED","attributes":[{"name":"line_note","value":""}]}]'),
('[{"id":"09237884-9713-9b6751fe0b85ffd","product_id":"dc85058a-a66b4c06702e13","register_id":"06bf5b9-31e2b4ac9d0a","sequence":"0","handle":"BricaBrac","sku":"20076","name":"Bric a Brac","quantity":1,"price":7,"cost":0,"price_set":1,"discount":-7,"loyalty_value":0.28,"tax":0,"tax_id":"dc85058a-2-54f20388394d","tax_name":"No Tax","tax_rate":0,"tax_total":0,"price_total":7,"display_retail_price_tax_inclusive":"1","status":"CONFIRMED","attributes":[{"name":"line_note","value":""}]},{"id":"09237884-9713-9b601235370","product_id":"dc85058a-a6fe112-6b4bfafb107e","register_id":"06bf537bf6b9-31e2b4ac9d0a","sequence":"1","handle":"LadiesTops","sku":"20040","name":"Ladies Tops","quantity":1,"price":10,"cost":0,"price_set":1,"discount":-10,"loyalty_value":0.4,"tax":0,"tax_id":"dc85058a-a690388394d","tax_name":"No Tax","tax_rate":0,"tax_total":0,"price_total":10,"display_retail_price_tax_inclusive":"1","status":"CONFIRMED","attributes":[{"name":"line_note","value":""}]},{"id":"09237884-9713-9b52007fa6c7d","product_id":"dc85058a-a6fa-b4c06d7ed5a","register_id":"06bf537b-cf6b9-31e2b4ac9d0a","sequence":"2","handle":"DVD","sku":"20077","name":"DVD","quantity":1,"price":3,"cost":0,"price_set":1,"discount":-3,"loyalty_value":0.12,"tax":0,"tax_id":"dc85058a-e5-e112-54f20388394d","tax_name":"No Tax","tax_rate":0,"tax_total":0,"price_total":3,"display_retail_price_tax_inclusive":"1","status":"CONFIRMED","attributes":[{"name":"line_note","value":""}]}]')
查询
SELECT id
FROM json_test
CROSS apply Openjson(json_col)
WITH (id varchar(500) 'lax $.id')
结果:
╔═══════════════════════════════╗
║ id ║
╠═══════════════════════════════╣
║ 429ac4e546-11e6-471e ║
║ 09237884-9713-9b6751fe0b85ffd ║
║ 09237884-9713-9b601235370 ║
║ 09237884-9713-9b52007fa6c7d ║
║ 429ac4e546-11e6-471e ║
║ 09237884-9713-9b6751fe0b85ffd ║
║ 09237884-9713-9b601235370 ║
║ 09237884-9713-9b52007fa6c7d ║
╚═══════════════════════════════╝
感谢 Prdp 的回复,引导我找到答案,如下所示。
SELECT a.ID, b.* -- select ID from original table for proofing, and all from table b
FROM reporttest a -- table name with alias
CROSS apply Openjson([register_sale_products]) -- column name
WITH (
id nvarchar(200) '$.id',
product_id nvarchar(200) '$.product_id',
register_id nvarchar(200) '$.register_id',
sequence nvarchar(200) '$.sequence',
handle nvarchar(200) '$.handle',
sku nvarchar(200) '$.sku',
name nvarchar(200) '$.name',
quantity nvarchar(200) '$.quantity',
price nvarchar(200) '$.price',
cost nvarchar(200) '$.cost',
price_set nvarchar(200) '$.price_set',
discount nvarchar(200) '$.discount',
loyalty_value nvarchar(200) '$.loyalty_value',
tax nvarchar(200) '$.tax',
tax_id nvarchar(200) '$.tax_id',
tax_name nvarchar(200) '$.tax_name',
--No Tax nvarchar(200) '$.No Tax',
tax_rate nvarchar(200) '$.tax_rate',
tax_total nvarchar(200) '$.tax_total',
price_total nvarchar(200) '$.price_total',
display_retail_price_tax_inclusive nvarchar(200) '$.display_retail_price_tax_inclusive',
status nvarchar(200) '$.status',
CONFIRMED nvarchar(200) '$.CONFIRMED',
attributes nvarchar(200) '$.attributes',
name nvarchar(200) '$.name',
line_note nvarchar(200) '$.line_note',
value nvarchar(200) '$.value'
) b -- alias the "with" section as table b
通过简单的 sql 查询不费吹灰之力,您将到达目的地。
make this query as stored procedure and call it when needed..
根据您的要求编辑此查询。
将“%id”:“”更改为“%anything_inside_the_string”,您将获得值..:)
DECLARE @LOOP_1 INT=1,@NAME NVARCHAR (MAX),@LEFT NVARCHAR(MAX),@loop_2 int=0
SET @NAME='[{"id":"429ac4e546-11e6-471e","product_id":"dc85bff3ecb24","register_id":"0adaaf5c4a65e37c7","sequence":"0","handle":"Skirts","sku":"20052","name":"Skirts","quantity":1,"price":5,"cost":0,"price_set":1,"discount":-5,"loyalty_value":0.2,"tax":0,"tax_id":"dc85058a-a69e-11e58394d","tax_name":"No Tax","tax_rate":0,"tax_total":0,"price_total":5,"display_retail_price_tax_inclusive":"1","status":"CONFIRMED","attributes":[{"name":"line_note","value":""}]}]'
-- First loop started to find where 'id":"' is located
WHILE @LOOP_1!=(SELECT LEN(@NAME))
BEGIN
SET @LEFT=(LEFT(@NAME,@LOOP_1))
IF @LEFT LIKE '%id":"' -------- Change '%id":"' to '%product_id":"' and you will get the value.. :)
BEGIN
set @NAME=(right(@NAME,len(@name)-@LOOP_1))
-- Second loop started to find where ',' is located after '"id":"'
WHILE @loop_2!=(SELECT LEN(@NAME))
BEGIN
SET @LEFT=(LEFT(@NAME,@loop_2))
IF @LEFT LIKE '%,'
BEGIN
if left(@name,@loop_2-1)like '%"%'
SELECT left(@name,@loop_2-2)
else
SELECT left(@name,@loop_2-2)
set @loop_2=(SELECT LEN(@NAME)-1)
set @loop_1=@loop_2
END
SET @loop_2=@loop_2+1
END
END
SET @LOOP_1=@LOOP_1+1
END