json - 使用 SQL Server 将 JSON 数组对象插入到两个表中
问题描述
我有一个应该 OPENJSON 并同时插入到两个表中的过程,JSON 数组中的每个对象都有一行。例如,数组中的这两个对象会将两行数据插入“case_idents”表并输出 2 个 case_ident_id(101 和 102)并将这两个 id 插入“case_to_case_idents”表。此过程不这样做,而是仅将 case_ident_id (102) 两次插入到“case_to_case_idents”表中,创建副本而不是创建唯一的行对象。
CREATE PROCEDURE case_idents_addAll
@case_ident_id INT OUTPUT,
@seq_id INT OUTPUT,
@identObj NVARCHAR(MAX),
/*
DECLARE @case_ident_id INT
DECLARE @seq_id INT
DECLARE @identObj NVARCHAR(MAX) = N'[
{
"name": "Jack",
"entityTypeCd": "SM",
"identStatus": "PR",
"caseId": 10034,
"caseStatusCd": "NUA"
},
{
"name": "Jill",
"entityTypeCd": "SF",
"identStatus": "PR",
"caseId": 10035,
"caseStatusCd": "NA"
}
]';
EXECUTE case_idents_addAll @identObj=@identObj, @case_ident_id=@case_ident_id OUTPUT, @seq_id=@seq_id OUTPUT
*/
AS
BEGIN
INSERT INTO case_idents
(name, entity_type_cd, ident_status, case_id)
SELECT name, entity_type_cd, ident_status, case_id
FROM OPENJSON(@identObj)
WITH (
name NVARCHAR(50) '$.name',
entity_type_cd CHAR(5) '$.entityTypeCd',
ident_status CHAR(5) '$.identStatus',
case_id INT '$.caseId'
)
SET @case_ident_id=SCOPE_IDENTITY();
INSERT INTO case_to_case_ident
(case_id, case_ident_id, case_status_cd, case_ident_status_cd)
SELECT case_id, @case_ident_id, case_status_cd, case_ident_status_cd
FROM OPENJSON(@identObj)
WITH (
case_id INT '$.caseId',
case_status_cd CHAR(5) '$.caseStatusCd',
case_ident_status_cd CHAR(5) '$.identStatus'
)
SET @seq_id = SCOPE_IDENTITY();
END
解决方案
您使用SCOPE_IDENTITY()的方式是为什么在第二次插入时两条记录具有相同的值。
SCOPE_IDENTITY() - 返回插入到同一范围内的标识列中的最后一个标识值。范围是一个模块:存储过程、触发器、函数或批处理。因此,如果两个语句在同一个存储过程、函数或批处理中,它们就在同一个范围内。
SCOPE_IDENTITY() 只会返回最后一个身份值。
如果您的 @identObj 数据中有唯一标识符,您可以使用OUTPUT 子句并在插入数据时将所有标识列值捕获到表变量中,然后在第二次插入中加入。
我问了这个问题,但我假设你也可以探索这个选项,case_id 在@identObj 中是唯一的。
--temp tables
CREATE TABLE [#case_idents]
(
[ID] INT IDENTITY
, [name] VARCHAR(255)
, [entity_type_cd] VARCHAR(255)
, [ident_status] VARCHAR(255)
, [case_id] INT
);
CREATE TABLE [#case_to_case_ident]
(
[case_id] INT
, [case_ident_id] INT
, [case_status_cd] VARCHAR(255)
, [case_ident_status_cd] VARCHAR(255)
);
--We'll use a table variable to capture all the identity field values at time of insert.
DECLARE @OutPut TABLE
(
[ID] INT
, [case_id] INT
);
DECLARE @identObj NVARCHAR(MAX) = N'[
{
"name": "Jack",
"entityTypeCd": "SM",
"identStatus": "PR",
"caseId": 10034,
"caseStatusCd": "NUA"
},
{
"name": "Jill",
"entityTypeCd": "SF",
"identStatus": "PR",
"caseId": 10035,
"caseStatusCd": "NA"
}
]';
INSERT INTO [#case_idents] (
[name]
, [entity_type_cd]
, [ident_status]
, [case_id]
)
--capture all the identities at time of insert into our table variable along with what the case_id was.
--Add OUTPUT right after your insert into the table variable. Will capture the inserted values, the identity values you're after and what case_id they are associated with
OUTPUT [Inserted].[ID]
, [Inserted].[case_id]
INTO @OutPut
SELECT [name]
, [entity_type_cd]
, [ident_status]
, [case_id]
FROM
OPENJSON(@identObj)
WITH (
[name] NVARCHAR(50) '$.name'
, [entity_type_cd] CHAR(5) '$.entityTypeCd'
, [ident_status] CHAR(5) '$.identStatus'
, [case_id] INT '$.caseId'
);
INSERT INTO [#case_to_case_ident] (
[case_id]
, [case_ident_id]
, [case_status_cd]
, [case_ident_status_cd]
)
SELECT [ident].[case_id]
, [op].[ID]
, [ident].[case_status_cd]
, [ident].[case_ident_status_cd]
FROM
OPENJSON(@identObj)
WITH (
[case_id] INT '$.caseId'
, [case_status_cd] CHAR(5) '$.caseStatusCd'
, [case_ident_status_cd] CHAR(5) '$.identStatus'
) AS [ident]
INNER JOIN @OutPut [op]
ON [op].[case_id] = [ident].[case_id]; --join here on case_id to get the identity value that was just created before that we captured and stored in our table variable.
SELECT *
FROM [#case_idents];
SELECT *
FROM [#case_to_case_ident];
推荐阅读
- java - 在具有 Criteria API 的 JPA 元模型中使用 volatile
- mysql - 在 Openshift 上创建 Keycloak 项目时出现有趣的 MySQL 错误
- karate - 为什么空手道不让我从另一个功能文件中读取变量?
- php - 根据会话 ID 在重复此查询时插入更新
- android - 使用 LayoutInflater 时 setTextSize 方法不起作用:
- node.js - 使用正则表达式捕获 utf-8 中的日期
- android - 在 XML 中设置 TextAppearance 后设置自定义字体不起作用
- maven - 在 IDE 的 maven 测试过程中不运行测试(使用 surefire)
- python - Pandas GroupBy 和计算 Z 分数
- shopify - Shopify 模版在哪里添加模版名称、创建者和模版版本?