我正在考虑使用存储过程来解决我必须更新/插入约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
作为参数,然后将其自身提取出来?
答案 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)
;
任何问题也请让我知道。