9

SQLデータベースにバイナリデータとして内部的に保存されているかなりの数の画像ファイルをエクスポートしようとしています。

SQLでストアドプロシージャを作成するのはかなり新しいので、これをアーカイブする方法について非常に役立つガイドをいくつか見つけましたが、何かが足りないようです。

SQL Server 2008 R2をローカルで実行していて、C:\ドライブ上のフォルダーにファイルを書き込もうとしています。

これが私がこれまでに持っているもののビジネスの部分です:

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

xp_cmdshellの呼び出し後、「@ result」は常に「1」(失敗)に設定されます。すべてのテーブル名/フィールドが正しいので、BCP呼び出しに問題があると思われますが、次に何を試すべきかわかりません。

どんな助けやアドバイスも大歓迎です。

4

2 に答える 2

7

さて、まず第一に..(そしてそれについては申し訳ありません;))カーソルを使用しないでください..そしてキャップについて申し訳ありません...

カーソルの最も悪い点の1つは、テーブルをロックできることです。私がこれらの目的のために常に行うこと(そしてこれは非常に高速です)、私は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

次の部分では、SQL Serverプロセスにc:ドライブに書き込むための十分なアクセス許可がありますか?また、コードを実行するときにメッセージペインを調べてください。おそらく、そこに何かが見つかりますか?

また、手動で実行してみてください。1つのBCPステートメントを取得し、xp_cmdshellを使用して実行するだけです。エラーが発生しますか?

于 2012-10-02T13:18:49.580 に答える
7

これが私の最終的な作業手順とフォーマットファイルです。BCP コマンド、パーミッション設定、フォーマット ファイル レイアウトの詳細を 1 か所で見つけることができなかったので、これが誰かの役に立つかもしれません。

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    

フォーマットファイル:

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

それが誰かに役立つことを願っています。

于 2012-10-04T08:22:19.560 に答える