Aunque estoy escribiendo mi propia respuesta, todo el crédito es para @Mikael Eriksson, quien sugirió que necesito separar diferentes lotes con GO, para que el código que altera la tabla no entre en conflicto con el código que usa la tabla alterada. ¡Gracias Mikael!
USE PUK;
GO
BEGIN TRANSACTION;
BEGIN TRY
-- - Modify RETRIEVAL_STAT
alter table dbo.RETRIEVAL_STAT add
SOURCE nvarchar(10) NULL,
ACCOUNTNUMBER nvarchar(50) NULL,
PUK nvarchar(20) NULL;
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
END CATCH;
IF @@TRANCOUNT > 0
COMMIT TRANSACTION;
GO
USE PUK;
GO
BEGIN TRANSACTION;
BEGIN TRY
-- transform logic.
UPDATE dbo.RETRIEVAL_STAT
SET SOURCE = 'ABC',
ACCOUNTNUMBER = ABC.ACCOUNTNUMBER,
PUK = ABC.PUK
FROM RETRIEVAL_STAT RS
INNER JOIN ABC
ON RS.SERVICE_NUMBER = ABC.SERVICENUMBER;
UPDATE dbo.RETRIEVAL_STAT
SET SOURCE = 'DEF',
ACCOUNTNUMBER = DEF.BILLINGACCOUNTNUMBER ,
PUK = DEF.PUK
FROM RETRIEVAL_STAT RS
INNER JOIN DEF
ON RS.SERVICE_NUMBER = DEF.SERVICENUMBER;
UPDATE dbo.RETRIEVAL_STAT
SET SOURCE = 'No Match'
WHERE SOURCE IS NULL;
-- Fix other columns that should be not nullable.
alter table dbo.RETRIEVAL_STAT
alter column SERVICE_NUMBER nvarchar (50) NOT NULL;
alter table dbo.DEF
alter column PUK nvarchar (20) NOT NULL;
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
END CATCH;
IF @@TRANCOUNT > 0
COMMIT TRANSACTION;
GO