Как заставить эту хранимую процедуру использовать проверку JSON? - PullRequest
0 голосов
/ 23 января 2019

Я смотрю на использование хранимой процедуры, чтобы помочь в ситуации, когда мне нужно обновить / вставить около 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 голосов
/ 30 января 2019

Надеюсь, я вас правильно понял. Пожалуйста, попробуйте это:

;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)
;

Любые вопросы, пожалуйста, дайте мне знать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...