Eu tenho um 'upsert' IF EXISTS funcionando bem sozinho em seu próprio proc armazenado. Mas quando tento usar a mesma instrução referenciando um CTE, ele não reconhece o CTE. Vejo no post relacionado que não tenho permissão para usar o CTE como a subconsulta. Estou curioso por que é isso, e de que outra forma eu poderia fazer isso?
Trabalhando o procedimento armazenado usando IF EXISTS:
ALTER Procedure [dbo].[sproc_receive]
@StockCode VARCHAR(50),
@Qty DECIMAL(18,6)
AS
--source: https://weblogs.sqlteam.com/dang/2007/10/28/conditional-insertupdate-race-condition/
SET NOCOUNT, XACT_ABORT ON
BEGIN TRAN
IF EXISTS(SELECT * FROM tblReceivedQty WITH (UPDLOCK, HOLDLOCK) WHERE StockCode = @StockCode)
BEGIN
UPDATE tblReceivedQty
SET ReceivedQty = ReceivedQty + @Qty
WHERE StockCode = @StockCode
END
ELSE
BEGIN
INSERT INTO tblReceivedQty (StockCode, ReceivedQty)
VALUES (@StockCode, @Qty)
END
COMMIT
RETURN @@ERROR
GO
E aqui está minha tentativa de redirecionar o IF EXISTS em outro proc armazenado que recebe uma string json como entrada.
USE [<databasename>]
GO
/****** Object: StoredProcedure [dbo].[sproc_PutAway] Script Date: 6/13/2022 4:14:02 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER Procedure [dbo].[sproc_PutAway]
(@json NVARCHAR(MAX) = '')
AS
BEGIN
-- Create CTE from JSON input
WITH json_received(StockCode, Qty)
AS
(
SELECT StockCode, Qty
FROM OPENJSON(@json)
WITH (
StockCode VARCHAR(30) '$.StockCode',
Qty DECIMAL(18,6) '$.Qty'
)
)
SET NOCOUNT, XACT_ABORT ON
BEGIN TRAN
IF EXISTS(SELECT * FROM tblReceivedQty WITH (UPDLOCK, HOLDLOCK) WHERE tblReceivedQty.StockCode = json_received.StockCode)
BEGIN
UPDATE tblReceivedQty
SET tblReceivedQty.ReceivedQty = tblReceivedQty.ReceivedQty - (
SELECT Sum(Qty)
FROM json_received
WHERE tblReceivedQty.StockCode = json_received.StockCode
GROUP BY json_received.StockCode
)
END
ELSE
BEGIN
INSERT INTO tblReceivedQty (StockCode, ReceivedQty)
VALUES (json_received.StockCode, (-1 * json_received.Qty))
END
COMMIT
RETURN @@ERROR
GO
Isso me dá um erro de sintaxe após o CTE e um 'identificador de várias partes não pôde ser vinculado' em todas as referências ao CTE.
Aprecie todas as dicas!