In my stored procedure, I have three insert statements.
On duplicate key value insertion first two queries generate the error
Violation o
The good news is a transaction in SQL Server can span multiple batches (each exec is treated as a separate batch.)
You can wrap your EXEC statements in a BEGIN TRANSACTION and COMMIT but you'll need to go a step further and rollback if any errors occur.
Ideally you'd want something like this:
BEGIN TRY
BEGIN TRANSACTION
exec( @sqlHeader)
exec(@sqlTotals)
exec(@sqlLine)
COMMIT
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
ROLLBACK
END CATCH
The BEGIN TRANSACTION and COMMIT I believe you are already familiar with. The BEGIN TRY and BEGIN CATCH blocks are basically there to catch and handle any errors that occur. If any of your EXEC statements raise an error, the code execution will jump to the CATCH block.
Your existing SQL building code should be outside the transaction (above) as you always want to keep your transactions as short as possible.