What you are using "RAISERROR" function is correct, if you use "PRINT" instead then it will print after all transactions are finished in current connection.
How do I get each statement to print directly after each successful insert, instead of all at once at the end?
it is already printing statement immediately after each successful insert, only thing is your query inserts only few records so both statements completed very quick so it looks like it printing all statement at once at the end of execution
I have already tried both approach with 500000 records insert in each query and found that "RAISERROR" using "WITH NOWAIT" prints messages immediately instead "PRINT" prints messages at the end of all transactions completed in current connection:
DECLARE @ErrorMessage AS NVARCHAR(MAX) = ''
BEGIN TRANSACTION;
BEGIN TRY
RAISERROR ('Token 1 started', 0, 1) WITH NOWAIT;
-- PRINT ('Token 1 started')
INSERT INTO [dbo].[DETAILS]
SELECT TOP 500000 [EMPNAME],[DEPT],[CONTACTNO],[CITY]
FROM [dbo].[DETAILS]
COMMIT TRANSACTION;
RAISERROR ('Token 1 completed successfully', 0, 1) WITH NOWAIT;
--PRINT ('Token 1 completed successfully')
END TRY
BEGIN CATCH
SET @ErrorMessage = ERROR_MESSAGE(); -- Store the error message in the variable
ROLLBACK TRANSACTION; -- Perform the rollback
RAISERROR ('Error inserting Token 1, rolling back', 0, 1) WITH NOWAIT;
RAISERROR (@ErrorMessage, 0, 1) WITH NOWAIT;
END CATCH;
-- Token 2
BEGIN TRANSACTION;
BEGIN TRY
RAISERROR ('Token 2 started', 0, 1) WITH NOWAIT;
-- PRINT ('Token 2 started')
INSERT INTO [dbo].[DETAILS]
SELECT TOP 500000 [EMPNAME],[DEPT],[CONTACTNO],[CITY]FROM [dbo].[DETAILS]
COMMIT TRANSACTION;
RAISERROR ('Token 2 completed successfully', 0, 1) WITH NOWAIT;
--PRINT ('Token 2 completed successfully')
END TRY
BEGIN CATCH
SET @ErrorMessage = ERROR_MESSAGE(); -- Store the error message in the variable
ROLLBACK TRANSACTION; -- Perform the rollback
RAISERROR ('Error inserting Token 2, rolling back', 0, 1) WITH NOWAIT;
RAISERROR (@ErrorMessage, 0, 1) WITH NOWAIT;
END CATCH;