简体   繁体   English

通过存储过程从SQL导出二进制文件数据(图像)

[英]Exporting binary file data (images) from SQL via a stored procedure

I am trying to export a fairly large number of image files, stored internally in an SQL database as binary data. 我试图导出相当大量的图像文件,内部存储在SQL数据库中作为二进制数据。

Being fairly new to writing stored procedures in SQL, I have come across a couple of very useful guides on how this can be archived, but I seem to be missing something. 作为在SQL中编写存储过程的新手,我已经遇到了一些关于如何存档的非常有用的指南,但我似乎错过了一些东西。

I am running SQL Server 2008 R2 locally, and I am trying to write the files to a folder on my C:\\ drive. 我在本地运行SQL Server 2008 R2,我正在尝试将文件写入我的C:\\驱动器上的文件夹。

Here is the buisness part of what I have so far: 这是我到目前为止的商业部分:

BEGIN
DECLARE @cmd VARCHAR(8000)
DECLARE @result int

DECLARE curExportBinaryDocs CURSOR FAST_FORWARD FOR
SELECT 'BCP "SELECT Photograph_Data FROM [ALBSCH Trial].[dbo].[Photograph] WHERE Photograph_ID = '
  + CAST(Photograph_ID AS VARCHAR(500)) + '" queryout "' + @OutputFilePath 
  + CAST(Photograph_ID AS VARCHAR(500)) + '.jpg"' + ' -n -T'
FROM dbo.Photograph

OPEN curExportBinaryDocs   
FETCH NEXT FROM curExportBinaryDocs INTO @cmd
WHILE @@FETCH_STATUS = 0
  BEGIN
     --PRINT @cmd
     EXEC @result = xp_cmdshell @cmd         
     FETCH NEXT FROM curExportBinaryDocs INTO @cmd
  END 
CLOSE curExportBinaryDocs
DEALLOCATE curExportBinaryDocs
END

'@result' is always being set to '1' (failed) after the xp_cmdshell call. 在xp_cmdshell调用之后,'@result'始终设置为'1'(失败)。 All the table names/fields are correct, so I suspect there is something wrong with my BCP call, but I am not sure what to try next. 所有的表名/字段都是正确的,所以我怀疑我的BCP电话有问题,但我不确定下一步该尝试什么。

Any help or advice would be very welcome. 任何帮助或建议都将非常受欢迎。

Here is my final working procedure and format file. 这是我的最终工作程序和格式文件。 I was not able to find the finer details of BCP commands, permision settings and format file layouts in one place, so maybe this will be of use to someone. 我无法在一个地方找到BCP命令,permision设置和格式文件布局的更精细细节,所以这可能对某人有用。

CREATE PROCEDURE [dbo].[ImgExport] 
   @OutputFilePath VARCHAR(500) = 'C:\SQLTest\ '
AS
BEGIN
   DECLARE @totrow int
   DECLARE @currow int
   DECLARE @result int
   DECLARE @nsql nvarchar(4000)
   DECLARE @sqlStatements table (ID int IDENTITY(1, 1),  SqlStatement varchar(max))   

   INSERT
   INTO @sqlStatements
   SELECT 'BCP "SELECT Photograph_Data FROM [ALBSCH_Trial].[dbo].[Photograph] WHERE  Photograph_ID = '''
     + CAST(Photograph_ID AS VARCHAR(500)) + '''" queryout ' + @OutputFilePath 
     + CAST(Photograph_ID AS VARCHAR(500)) + '.jpg -S localhost\SQLEXPRESS2008 -T -f C:\SQLTest\Images.fmt'
   FROM dbo.Photograph  

   SET @totrow = @@ROWCOUNT
   SET @currow = 1
   WHILE @totrow > 0 and @currow <= @totrow
   BEGIN
      SELECT @nsql = SqlStatement
      FROM @sqlStatements
      WHERE ID = @currow
      EXEC @result = xp_cmdshell @nsql
      SET @currow = @currow + 1
   END
END    

Format file: 格式文件:

9.0  
1  
1       SQLBINARY       0       0       "\t"     1      Photograph_Data                                  ""

I hope that helps somebody. 我希望能帮到别人。

Well, first of all.. (and sorry about that ;) ) DON"T USE CURSORS.. and sorry for the caps... 好吧,首先......(并对此感到抱歉;))DON“T使用游标......并且对不起盖帽......

One of the most baddest things about cursors are that they can lock your table. 关于游标最糟糕的事情之一是他们可以锁定你的桌子。 What i always do for these purposes (and which is quite faster), i use a for loop.. like this 我总是为这些目的做的(而且速度更快),我使用for循环..就像这样

declare @totrow int
      , @currow int
      , @result int
      , @nsql nvarchar(max)

declare @sqlStatements table (
  Id int identity(1, 1)
, SqlStatement varchar(max)
)
insert 
into    @sqlStatements
select  'QUERY PART'
from    table

set @totrow = @@rowcount
set @currow = 1
while @totrow > 0 and @currow <= @totrow
begin
  select @nsql = SqlStatement
  from   @SqlStatements
  where  Id = @currow

  exec @result = xp_cmdshell @nsql

  set @currow = @currow + 1
end

For the next part, does the SQL Server process has enough permission to write to the c: drive? 对于下一部分,SQL Server进程是否有足够的权限写入c:驱动器? Also, look into your message pane when you execute your code, maybe you can find something there? 另外,在执行代码时查看消息窗格,也许你可以在那里找到一些东西?

What you also can do, try to execute it manually. 你也可以做什么,尝试手动执行它。 Just get one BCP statement and execute it with the xp_cmdshell. 只需获取一个BCP语句并使用xp_cmdshell执行它。 Does it gives any errors? 它有任何错误吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM