IF EXISTS(检查json对象是否包含唯一ID),UPDATE表,ELSE INSERT插入表

时间:2018-10-31 17:59:05

标签: json sql-server tsql if-statement

我想在查询中使用IF EXISTS来检查对象是否包含“ seqId”。我正在尝试从OPENJSON更新或插入到表中。 json对象@identObj具有对象数组,某些对象可能具有“ seqId”,而某些对象可能没有。具有“ seqId”的对象应更新到“ case_ident_to_inv”表中,如果“ seqId”不存在,则应将其插入该表中的“ case_ident_to_inv”表中。插入表的输出是唯一的seqId。我尝试实现IF EXISTS语句,但我认为语法正确,但出现此错误:

  

'IF'附近的语法不正确。

DECLARE @identObj NVARCHAR(MAX) = N'[
  {  
    "investigators": [
         {"importId": 177, "userId": 120, "invTypeCd": "LI", "seqId": 50}, 
         {"importId": 177, "userId": 124, "invTypeCd": "SI", "seqId": 50}, 
         {"importId": 177, "userId": 120, "invTypeCd": "RV", "seqId": 50}, 
         {"importId": 177, "userId": 123, "invTypeCd": "SI"},
     ]
   }
]';

“ case_ident_to_inv”表的数据

+------------+--------+-------------+---------------+-------+
|  importId  | userId |  invTypeCd  |  caseIdentId  | seqId |
+------------+--------+-------------+---------------+-------+
| 177        | 120    | LI          | 10200         | 50    | 
| 177        | 124    | SI          | 10200         | 51    | 
| 177        | 120    | RV          | 10200         | 52    |
| 177        | 123    | SI          | 10200         |       |<--- seqId OUTPUT AFTER INSERT
+------------+--------+-------------+---------------+-------+

caseIdentId和importId将始终相同,可以有相同的userId和invTypeCd,seqId始终是唯一的。

存储过程

select I.*
INTO #tmpInvs
FROM OPENJSON(@identObj)
WITH (
    invs NVARCHAR(MAX) AS JSON
) AS caseIdentInvs
CROSS APPLY OPENJSON (caseIdentInvs.invs)
WITH (
    userId INT,
    invTypeCd CHAR(5),
    importId INT,
    seqId INT
) I;

WITH cte AS
(
    SELECT i.*,ci.case_ident_id AS case_ident_id, ki.inv_type_name AS inv_type_name
    FROM #tmpInvs i
    INNER JOIN case_idents ci ON i.importId=ci.import_id
    INNER JOIN kdd_inv_type ki ON i.invTypeCd=ki.inv_type_cd
)

IF EXISTS (SELECT i.seqId FROM #tmpInvs i WHERE i.seqId != NULL)
UPDATE T
SET
    inv_id = ct.userId,
    inv_type_cd = ct.invTypeCd,
    inv_type_name = ct.inv_type_name
FROM case_ident_to_inv T
INNER JOIN cte AS ct ON ct.case_ident_id = T.case_ident_id

WHERE seq_id = ct.seqId

ELSE

INSERT INTO case_ident_to_inv(inv_id, case_ident_id, inv_type_cd, inv_type_name)
SELECT userId, case_ident_id, invTypeCd, inv_type_name
FROM cte

2 个答案:

答案 0 :(得分:2)

您不能将IF放在cte声明之后,因为下一个命令是必须使用cte的命令。但是,您可以使用单个merge语句替换if / update / insert结构。像这样:

def attached_form(self):
    return self.contact_form.specific.get_form()

答案 1 :(得分:1)

CTE 需要 merge case_ident_to_inv as Target using (select * from cte) as Source on Target.case_ident_id = Source.case_ident_id when matched then update set inv_id = Source.userId, inv_type_cd = Source.invTypeCd, inv_type_name = Source.inv_type_name when not matched then insert(inv_id, case_ident_id, inv_type_cd, inv_type_name) values(Source.userId, Source.case_ident_id, Source.invTypeCd, Source.inv_type_name); 。来自Docs

  

在CTE之后必须是引用某些或所有CTE列的单个SELECT,INSERT,UPDATE或DELETE语句。也可以在CREATE VIEW语句中指定CTE作为视图的定义SELECT语句的一部分。

您可以将SELECT, INSERT, UPDATE or DELETE向上移动为

IF EXISTS