若存在(检查json对象是否包含唯一id),则更新表,否则插入表

若存在(检查json对象是否包含唯一id),则更新表,否则插入表,json,sql-server,tsql,if-statement,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”附近的语法不正确

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

“IF”附近的语法不正确

“案例识别到库存”表的数据


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

    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);
CTE需要
选择、插入、更新或删除
。发件人:

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

如果存在
,您可以将
向上移动,如下所示

   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;
    IF EXISTS (SELECT i.seqId FROM #tmpInvs i WHERE i.seqId != NULL)
    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
    )
    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

CTE不需要选择、插入、更新或删除
其他内容。您可以在CTE之前使用
IF EXISTS
。IF语句有效,但我没有得到我想要的结果。所有对象都被插入到表中,而不是更新已经有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
    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);
   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;
    IF EXISTS (SELECT i.seqId FROM #tmpInvs i WHERE i.seqId != NULL)
    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
    )
    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