如何使此存储过程使用JSON检查?

时间:2019-01-23 17:01:22

标签: sql json sql-server stored-procedures sql-server-2017

我正在考虑使用存储过程来解决我必须更新/插入约1000条记录的情况。有人建议我将MERGE与一个表值参数一起使用来实现此目的,但问题是列之一是JSON字符串。

ItemsTbl

id -PK
BrandId- int (FK)
LocationId- int (FK)
Field3 - nvarchar(Max) Json string containing a jsonKey called itemNumber


select * 
from ItemsTbl 
where BrandId = 1 
  and LocationId = 1 
  and JSON_VALUE('Field3',$.itemNumber) = 12345

现在,存储过程(对我来说几乎是所有新东西)现在看起来像这样:

/* Create a table type. */  
CREATE TYPE SourceTableType AS TABLE   
( BrandId INT  
, LocationId INT
, ItemNumber INT
, ...
);  
GO 

CREATE PROCEDURE dbo.usp_InsertTvp  
    @Source SourceTableType READONLY  
AS        
    MERGE INTO Table1 AS Target  
    USING @Source As Source ON Target.BrandId = Source.BrandId 
                            AND Target.LocationId = Source.LocationId 
                            AND Target.ItemNumber = Source.ItemNumber  

    WHEN MATCHED THEN  
        UPDATE SET OtherParam = Source.OtherParam  

    WHEN NOT MATCHED BY TARGET THEN  
        INSERT (BrandId, LocationId, ItemNumber, OtherParam) 
        VALUES (BrandId, LocationId, ItemNumber, OtherParam) ;

问题在于,现在看来,ItemNumber不在JSON字符串中而且不是它自己的列,这似乎无法说明。所以我认为这不会起作用

 Target.ItemNumber = Source.ItemNumber  

我还猜测SourceTableType必须接受Field3作为参数,然后将其自身提取出来?

1 个答案:

答案 0 :(得分:0)

希望我能正确理解你。 请尝试以下方法:

;WITH MergeTarget AS (
    SELECT t.BrandId,t.LocationId,t.Field3,JSON_VALUE(t.Field3,'$.itemNumber') AS [ItemNumber],t.OtherParam
    FROM Table1 AS t
)
MERGE MergeTarget AS target
USING (
    SELECT s.BrandId,s.LocationId,s.ItemNumber,'{"itemNumber":"'+CONVERT(NVARCHAR(255),s.ItemNumber)+'"' AS [Field3],s.OtherParam
    FROM @Source AS s
) AS source ON source.BrandId = target.BrandId
    AND source.LocationId = target.LocationId
    AND source.ItemNumber = target.ItemNumber
WHEN MATCHED AND target.OtherParam <> source.OtherParam THEN UPDATE SET target.OtherParam = source.OtherParam
WHEN NOT MATCHED THEN INSERT (BrandId, LocationId, Field3, OtherParam) 
    VALUES(source.BrandId,source.LocationId,source.Field3,source.OtherParam)
;

任何问题也请让我知道。