解析 JSON 数据并插入到 SQL Server 中的多个表中
Posted
技术标签:
【中文标题】解析 JSON 数据并插入到 SQL Server 中的多个表中【英文标题】:Parse JSON data and insert into multiple tables in SQL Server 【发布时间】:2021-07-07 08:19:26 【问题描述】:我有一个 JSON,其中包含以下格式的客户信息
"customerdata": [
"customerID": "abcsd112-1234-4c01-abcd-bb2fb084dc52",
"customerDetails": [
"fieldId": "100",
"fieldValue": "ABC"
,
"fieldId": "101",
"fieldValue": "TESTCUSTOMER001"
,
"fieldId": "102",
"fieldValue": "1000"
,
"fieldId": "103",
"fieldValue": "TESTNAME"
]
,
"customerID": "cdfsd112-4c01-45d7-abcd-9c9662d4ca30",
"customerDetails": [
"fieldId": "100",
"fieldValue": "CDE"
,
"fieldId": "101",
"fieldValue": "TESTCUSTOMER002"
,
"fieldId": "102",
"fieldValue": "1002"
,
"fieldId": "103",
"fieldValue": "TESTNAME2"
]
]
从这个 JSON 数据中,我想将数据插入两个单独的表中。这样,客户 ID 详细信息到一个表 (CustomerDetails) 和客户字段详细信息 (customerDetails json 节点) 到另一个表 (CustomerFieldData) 的外键引用第一个表(客户 ID)。
所以下面是需要的表格
-
CustomerDetails 表结构,其中来自 JSON 的 customerID 应插入到 CustomerUniqueGUID 列,客户名称将来自 customerDetails json 节点的字段 id 101
CREATE TABLE [CustomerDetails](
[CustomerID] [bigint] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[CustomerUniqueGUID] UNIQUEIDENTIFIER NOT NULL,
[CustomerName] [varchar](100) NULL,
[IsActive] [bit] NULL)
客户字段数据表
CREATE TABLE [CustomerFieldData](
[CustomerFieldDataID] [bigint] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[CustomerID] [bigint] NOT NULL FOREIGN KEY REFERENCES [CustomerDetails] ([CustomerID]),
[FieldID] [varchar](100) NOT NULL,
[FieldValue] [varchar](100) NOT NULL)
我已经创建了一个示例存储过程来做同样的事情。
ALTER PROCEDURE [InsertCustomerInfo]
@CustomerJson NVarchar(MAX)
AS
BEGIN
INSERT INTO CustomerDetails (CustomerUniqueGUID,CustomerName)
SELECT Customer.customerID, Fields.fieldValue FROM
OPENJSON(@CustomerJson)
WITH ([customerdata] nvarchar(max) as json
) AS CustomerBatch
cross apply openjson (CustomerBatch.[customerdata])
with
(
customerID varchar(100),
customerDetails nvarchar(max) as json
) AS Customer
cross apply openjson (Customer.customerDetails) with
(
fieldId nvarchar(100),
fieldValue nvarchar(max)
) as Fields
WHERE Fields.fieldID='101'
AND CustomerDetails.CustomerUniqueGUID not in (SELECT CustomerUniqueGUID FROM CustomerDetails WHERE ISActive=1 )
If @@ROWCOUNT > 0
BEGIN
INSERT INTO [CustomerFieldData](CustomerID,FieldID,FieldValue) SELECT L.CustomerID,Fields.fieldId,Fields.fieldValue FROM
CustomerDetails L INNER JOIN
OPENJSON(@CustomerJson)
WITH ([customerdata] nvarchar(max) as json
) AS CustomerBatch
cross apply openjson (CustomerBatch.[customerdata])
with
( customerID varchar(100),
customerDetails nvarchar(max) as json
) AS Customer
cross apply openjson (Customer.customerDetails) with
(
fieldId nvarchar(100),
fieldValue nvarchar(max)
) as Fields
ON L.CustomerUniqueGUID=Customers.customerID
END
END
但是到 CustomerFieldData 的数据没有正确发生并且需要更多时间。我的脚本有问题吗?请帮忙。
【问题讨论】:
为什么CustomerUniqueGUID
是varchar(100)
而不是uniqueidentifier
?
@Larnu:它是一个 guid,它将是字母数字
这不能回答我的问题... 'cdfsd112-4c01-45d7-abcd-9c9662d4ca30'
的值显然是一个 GUID,那么为什么将 CustomerUniqueGUID
定义为 varchar(100)
?跨度>
@Larnu: uniqueidentifier 是可用的数据类型吗?
是的...从我记事起就一直存在。
【参考方案1】:
您可以在此处使用 INSERT
和 OUTPUT
来获取新 ID 和 GUID 的值:
DECLARE @JSON nvarchar(MAX) = N'
"customerdata": [
"customerID": "abcsd112-1234-4c01-abcd-bb2fb084dc52",
"customerDetails": [
"fieldId": "100",
"fieldValue": "ABC"
,
"fieldId": "101",
"fieldValue": "TESTCUSTOMER001"
,
"fieldId": "102",
"fieldValue": "1000"
,
"fieldId": "103",
"fieldValue": "TESTNAME"
]
,
"customerID": "cdfsd112-4c01-45d7-abcd-9c9662d4ca30",
"customerDetails": [
"fieldId": "100",
"fieldValue": "CDE"
,
"fieldId": "101",
"fieldValue": "TESTCUSTOMER002"
,
"fieldId": "102",
"fieldValue": "1002"
,
"fieldId": "103",
"fieldValue": "TESTNAME2"
]
]
';
CREATE TABLE #CustomerIDs (CustomerID bigint,
CustomerUniqueGUID varchar(100)) ;
INSERT INTO dbo.CustomerDetails (CustomerUniqueGUID,CustomerName)
OUTPUT inserted.CustomerID, inserted.CustomerUniqueGUID
INTO #CustomerIDs
SELECT OJ.customerID,
CD.fieldValue
FROM OPENJSON(@JSON,'$.customerdata')
WITH(customerID varchar(100),
customerDetails nvarchar(MAX) AS JSON) OJ
CROSS APPLY OPENJSON(OJ.customerDetails)
WITH(fieldId int,
fieldValue varchar(100)) CD
WHERE CD.fieldID = 101;
INSERT INTO dbo.CustomerFieldData (CustomerID,FieldID,FieldValue)
SELECT CI.CustomerID,
CD.fieldID,
CD.fieldValue
FROM OPENJSON(@JSON,'$.customerdata')
WITH (customerID varchar(100), --Let's use the right data type again
customerDetails nvarchar(MAX) AS JSON) OJ
CROSS APPLY OPENJSON(OJ.customerDetails)
WITH(fieldId int,
fieldValue varchar(100)) CD
JOIN #CustomerIDs CI ON OJ.customerID = CI.CustomerUniqueGUID
DROP TABLE #CustomerIDs;
GO
SELECT *
FROM dbo.CustomerDetails;
SELECT *
FROM dbo.CustomerFieldData;
【讨论】:
以上是关于解析 JSON 数据并插入到 SQL Server 中的多个表中的主要内容,如果未能解决你的问题,请参考以下文章
使用 c# asp.net 获取 XML 数据并插入到 sql server
使用 C# 和 OPENJSON 将 JSON 插入 SQL Server 2016