我尝试使用open json插入订单信息和订单行。
这是json的例子。
declare @json nvarchar(max) = '
{"OrderID":0,
"CustomerID":2250,
"SupplierID":1,
"CuratorID":988,
"FirmID":null,
"OrderStateID":2,
"DeliveryTypeID":1,
"Code1C":"",
"CreationDate":"2017-11-12T01:05:14.3233187+03:00",
"ReservationDate":"2017-11-15T01:05:16.1306759+03:00",
"AssemblyDate":null,
"DeliveryDate":"2017-11-12T01:05:15.1748244+03:00",
"TransportAddress":"",
"TransportName":"","TransportPhone":"","RecieverAddress":"","RecieverName":"",
"RecieverPhone":"","Comment":"","LoaderID":null,"DriverID":null,
"CanDelete":true,"LoadingDate":null,"RealizeNum":"","IsDocumentsCreate":false,"DeliveryType":null,"Firm":null,
"OrderLines":[
{"OrderLineID":0,"OrderID":0,"ProductID":1,"ProductCount":100,"ChangeCount":0,"Price":363.0,"Product":null,"Order":null},
{"OrderLineID":0,"OrderID":0,"ProductID":3,"ProductCount":100,"ChangeCount":0,"Price":860.0,"Product":null,"Order":null}
]}'
现在我在Orders表中插入主要信息。
insert into Sales.Orders (CustomerID
,SupplierID
,CuratorID
,OrderStateID
,FirmID
,DeliveryTypeID
,Code1C
,CreationDate
,ReservationDate
,DeliveryDate) select * from openjson(@s) with
(CustomerID int, SupplierID int,
CuratorID int, OrderStateID int, FirmID int, DeliveryTypeID int, Code1C nvarchar(10),
CreationDate datetime2, ReservationDate datetime2, DeliveryDate datetime2);
select * from openjson(@s);
工作正常。下一步我需要插入订单行数组。但在插入之前,我需要将OrderID设置为每个订单行。
这里我选择最后插入的订单标识。
declare @ident int;
select @ident = SCOPE_IDENTITY();
但我不明白,如何将此值设置为每个订单行。 下一个代码不起作用
set @json = JSON_MODIFY(@s, '$.OrderLines.OrderID', @ident);
感谢您的任何建议
答案 0 :(得分:0)
由于OrderLines是一个数组,您需要分别引用每一行。
在这种情况下,您需要为数组中的每个对象分别使用两个语句:
set @json = JSON_MODIFY(@json, '$.OrderLines[0].OrderID', @ident);
set @json = JSON_MODIFY(@json, '$.OrderLines[1].OrderID', @ident);
关于如何使用t-SQL引用JSON中的各种元素的好读物是https://www.codeproject.com/Articles/1125457/Native-JSON-Support-in-SQL-Server。
要找出可以使用的行数:
SELECT count(*)
FROM OPENJSON(@json, '$.OrderLines')
然后您可以使用光标循环浏览项目。
例如:
declare @count int;
declare @index int = 0;
declare @sql nvarchar(1000);
declare @parmasDef nvarchar(1000);
select @count = count(*)
from OPENJSON(@json, '$.OrderLines');
set @parmasDef = N'@json nvarchar(max) output,@ident int'
while @index < @count
begin
set @sql = N'set @json = JSON_MODIFY(@json, ''$.OrderLines[' + cast(@index as nvarchar(10)) + '].OrderID'', @ident);'
exec sp_executesql @sql, @parmasDef, @json = @json output, @ident=@ident
set @index += 1;
end
print @json
答案 1 :(得分:0)
您也可以使用基于集合的逻辑来执行此操作,而不是在SQL中进行while循环。您需要使用STRING_AGG
而不是FOR JSON PATH/AUTO
,因为将对象重新组合在一起时,它们没有根。
DECLARE
@json nvarchar(max) = N'{
"SomeOtherJson": "bleh",
"OrderLines":[
{"OrderLineID":0,"OrderID":0,"ProductID":1,"ProductCount":100,"ChangeCount":0,"Price":363.0,"Product":null,"Order":null},
{"OrderLineID":0,"OrderID":0,"ProductID":3,"ProductCount":100,"ChangeCount":0,"Price":860.0,"Product":null,"Order":null}
]}',
@Id INT = 1;
WITH OrderLines AS (
SELECT JSON_MODIFY(t.[value], '$.OrderID', @Id) OrderLine, @Id Id
FROM OPENJSON((SELECT JSON_QUERY(@json, 'lax $.OrderLines'))) t
), OrderLineList AS (
SELECT CONCAT('[',STRING_AGG(t.OrderLine, ','),']') OrderLines
FROM OrderLines t
GROUP BY t.Id
)
SELECT JSON_MODIFY(@json, '$.OrderLines', JSON_QUERY(t.OrderLines))
FROM OrderLineList t
导致(美化)的结果:
{
"SomeOtherJson": "bleh",
"OrderLines": [
{
"OrderLineID": 0,
"OrderID": 1,
"ProductID": 1,
"ProductCount": 100,
"ChangeCount": 0,
"Price": 363,
"Product": null,
"Order": null
},
{
"OrderLineID": 0,
"OrderID": 1,
"ProductID": 3,
"ProductCount": 100,
"ChangeCount": 0,
"Price": 860,
"Product": null,
"Order": null
}
]
}
答案 2 :(得分:0)
不是真正的答案,但为了扩展@ Jon49的答案,基于集的操作也可以使用VARCHAR(MAX)
应用于具有CROSS APPLY
列作为JSON的表。例如:
DECLARE @orders TABLE(Id int, ORDERLINES NVARCHAR(MAX));
INSERT INTO @orders (Id, ORDERLINES) VALUES (1, N'{
"OrderLines":[
{"OrderLineID":1,"OrderID":0,"ProductID":1,"ProductCount":100,"ChangeCount":0,"Price":363.0,"Product":null,"Order":null},
{"OrderLineID":2,"OrderID":0,"ProductID":3,"ProductCount":100,"ChangeCount":0,"Price":860.0,"Product":null,"Order":null}
]}')
INSERT INTO @orders (Id, ORDERLINES) VALUES (2, N'{
"OrderLines":[
{"OrderLineID":3,"OrderID":0,"ProductID":1,"ProductCount":22,"ChangeCount":0,"Price":363.0,"Product":null,"Order":null},
{"OrderLineID":4,"OrderID":0,"ProductID":3,"ProductCount":33,"ChangeCount":0,"Price":860.0,"Product":null,"Order":null}
]}');
WITH OrderLines AS (
SELECT JSON_MODIFY(t.[value], '$.OrderID', o.Id) OrderLine, o.Id
FROM @orders o
CROSS APPLY OPENJSON((SELECT JSON_QUERY(o.ORDERLINES, 'lax $.OrderLines'))) t
), OrderLineList AS (
SELECT CONCAT('[',STRING_AGG(t.OrderLine, ','),']') OrderLines, t.Id
FROM OrderLines t
GROUP BY t.Id
)
SELECT JSON_MODIFY(o.ORDERLINES, '$.OrderLines', JSON_QUERY(t.OrderLines))
FROM OrderLineList t
INNER JOIN @orders o ON (o.Id=t.Id);