在不使用动态SQL的情况下更新从文件系统获取文件的二进制字段

时间:2015-03-17 17:50:38

标签: sql-server tsql sql-server-2005 try-catch openrowset

情景

我在Sql Server 2005中有一个表(让我们称之为myTable),其中有一些列,包括varbinary(max)字段:

  • REPORT_ID int (主键)
  • REPORT_FILE varbinary(max)
  • ...

我经常需要通过从文件系统读取文件的TSQL脚本来更新varbinary(max)列中包含的文件。这些脚本在Sql Server Management Studio中执行。

我编写了以下脚本来使用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 

问题

我想处理文件丢失或文件名错误的情况;期望的行为是:

  • rollback如果发生错误
  • commit如果一切正常

如果缺少输入文件,则上述脚本会生成错误,但CATCH块无法捕获异常,因此事务和myOtherTable的更新仍然未决,因为{{1} }指令没有被执行。因此,我必须手动回滚事务。

我的解决方案

我发现捕获COMMIT块中的错误的唯一方法是使用动态TSQL,所以我的实际脚本是:

CATCH

问题

是否可以在不使用动态TSQL的情况下实现所需的行为?

1 个答案:

答案 0 :(得分:2)

最好只检查文件是否存在。

DECLARE @isExists INT;
EXEC master.dbo.xp_fileexist 'C:\filename.ext', @isExists OUTPUT

--If the file exists, then 
IF(@isExists = 1)
BEGIN
    SELECT 'It exists!'
    --Do your work here
END
ELSE
BEGIN
    --Return some kind of error message
    SELECT 'File does not exist.'
END