Как прокомментировал @ Felipe-Martins, оператор MERGE может немного упростить ситуацию.
MERGE явно не решает конкретный вопрос, который у вас был о динамическом повторном использовании существующего _idref или создании нового с помощью newid (), но это легко решить, обернув вызов isnull()
вокруг вашего подзапроса.
Вероятно, есть лучшее решение, но в течение первого часа с тех пор, как вы отправили сообщение, об этом не было много действий, поэтому я решил сохранить это сообщение, а не выбрасывать его на случай, если оно поможет.
declare @LGRACT bigint
declare @SUBACT bigint
declare @AMOUNT decimal(12,2)
declare @PostYear smallint
declare @PostMonth tinyint
set @PostYear=2018
set @PostMonth=12
set @LGRACT = 6000
set @SUBACT = 200
set @AMOUNT = 2000.00
MERGE [Services Copy].dbo.lgrbal AS target
USING (SELECT @LGRACT, @AMOUNT, @PostYear, @PostMonth) AS source
(lgract, amount, postyr, actprd)
ON (
target.lgract = source.lgract and
target.postyr = source.postyr and
target.actprd = source.actprd
)
WHEN MATCHED THEN
UPDATE SET target.Balance = target.Balance + source.amount
WHEN NOT MATCHED THEN
INSERT (
_idnum,
_idref,
lgract,
postyr,
actprd,
balnce
)
VALUES (
newid(),
isnull(
(select top 1 _idref
from [Services Copy].dbo.lgrbal
where lgract=@LGRACT and postyr=@PostYear),
newid()),
source.lgract,
source.postyr,
source.actprd,
source.balance
)