The Scenario
I have a table (let's call it myTable) in Sql Server 2005 with some columns, including a varbinary(max) field:
- REPORT_ID
int(primary key) - REPORT_FILE
varbinary(max) - ...
I often need to update the files contained inside the varbinary(max) column via TSQL scripts reading a file from the filesystem. These scripts are executed in Sql Server Management Studio.
I wrote the following script to update the binary value using OPENROWSET:
begin try
begin tran
update myOtherTable set field1 = 'value1'
--other instructions
--...
UPDATE myTable
SET [REPORT_FILE] = (SELECT * FROM OPENROWSET(BULK 'c:\filename.ext', SINGLE_BLOB) AS T)
WHERE REPORT_ID = ...
end try
begin catch
if @@TRANCOUNT > 0 begin
rollback tran
--other instructions for error handling
--...
end
end catch
if @@TRANCOUNT > 0 begin
commit tran
end
The Problem
I want to handle the scenario where the file is missing or the filename is wrong; the desired behavior is:
rollbackif an error occurscommitif everything worked
If the input file is missing the above script generates an error, but the CATCH block fails to capture the exception, so the transaction and the update to myOtherTable remain pending because the COMMIT instruction isn't executed. As a result I have to rollback the transaction manually.
My solution
The only way I have found to capture the error in the CATCH block is using dynamic TSQL, so my actual script is:
declare @dSQL nvarchar(max)
begin try
begin tran
update myOtherTable set field1 = 'value1'
--other instructions
--...
set @dSQL = '
UPDATE myTable
SET [REPORT_FILE] = (SELECT * FROM OPENROWSET(BULK ''c:\filename.ext'', SINGLE_BLOB) AS T)
WHERE REPORT_ID = ...
'
exec sp_executesql @dSQL
end try
begin catch
if @@TRANCOUNT > 0 begin
rollback tran
--other instructions for error handling
--...
end
end catch
if @@TRANCOUNT > 0 begin
commit tran
end
The Question
Is it possible to achieve the desired behavior without using dynamic TSQL?
Aucun commentaire:
Enregistrer un commentaire