webentwicklung-frage-antwort-db.com.de

schnellste Weg, um Blobs aus einer Tabelle in einzelne Dateien zu exportieren

Was ist der schnellste Weg, um in einer SQL Server-Tabelle gespeicherte Dateien (Blobs) in eine Datei auf der Festplatte zu exportieren? Ich habe über 2,5 TB von Dateien (90 kb Durchschnitt) als Varbinary gespeichert und ich muss jede so schnell wie möglich auf eine lokale Festplatte extrahieren. BCP scheint zu funktionieren, aber es wird übernehmen 45 Tage mit der Geschwindigkeit, die ich sehe, und ich bin besorgt, dass mein Skript irgendwann fehlschlagen wird, weil Management Studio nicht mehr genügend Arbeitsspeicher zur Verfügung steht.

28
influent

Ich habe versucht, eine CLR-Funktion zu verwenden, die mehr als doppelt so schnell war wie BCP. Hier ist mein Code.

Originalmethode:

SET @bcpCommand = 'bcp "SELECT blobcolumn FROM blobtable WHERE ID = ' + CAST(@FileID AS VARCHAR(20)) + '" queryout "' + @FileName + '" -T -c'
EXEC master..xp_cmdshell @bcpCommand

CLR-Methode:

declare @file varbinary(max) = (select blobcolumn from blobtable WHERE ID = @fileid)
declare @filepath nvarchar(4000) = N'c:\temp\' + @FileName
SELECT Master.dbo.WriteToFile(@file, @filepath, 0)

C # -Code für die CLR-Funktion

using System;
using System.Data;
using System.Data.SqlTypes;
using System.IO;
using Microsoft.SqlServer.Server;

namespace BlobExport
{
    public class Functions
    {
      [SqlFunction]
      public static SqlString WriteToFile(SqlBytes binary, SqlString path, SqlBoolean append)
      {        
        try
        {
          if (!binary.IsNull && !path.IsNull && !append.IsNull)
          {         
            var dir = Path.GetDirectoryName(path.Value);           
            if (!Directory.Exists(dir))              
              Directory.CreateDirectory(dir);            
              using (var fs = new FileStream(path.Value, append ? FileMode.Append : FileMode.OpenOrCreate))
            {
                byte[] byteArr = binary.Value;
                for (int i = 0; i < byteArr.Length; i++)
                {
                    fs.WriteByte(byteArr[i]);
                };
            }
            return "SUCCESS";
          }
          else
             "NULL INPUT";
        }
        catch (Exception ex)
        {          
          return ex.Message;
        }
      }
    }
}
30
influent

Ich bin hierher gekommen, um mit geringstem Aufwand Blob in eine Datei zu exportieren. CLR-Funktionen sind nicht das, was ich als geringsten Aufwand bezeichnen würde. hier beschrieben lazier one, using OLE Automation:

declare @init int
declare @file varbinary(max) = CONVERT(varbinary(max), N'your blob here')
declare @filepath nvarchar(4000) = N'c:\temp\you file name here.txt'

EXEC sp_OACreate 'ADODB.Stream', @init OUTPUT; -- An instace created
EXEC sp_OASetProperty @init, 'Type', 1; 
EXEC sp_OAMethod @init, 'Open'; -- Calling a method
EXEC sp_OAMethod @init, 'Write', NULL, @file; -- Calling a method
EXEC sp_OAMethod @init, 'SaveToFile', NULL, @filepath, 2; -- Calling a method
EXEC sp_OAMethod @init, 'Close'; -- Calling a method
EXEC sp_OADestroy @init; -- Closed the resources

Möglicherweise müssen Sie zulassen, dass gespeicherte OA-Prozeduren auf dem Server ausgeführt werden (und dann deaktivieren, wenn Sie fertig sind):

sp_configure 'show advanced options', 1;  
GO  
RECONFIGURE;  
GO  
sp_configure 'Ole Automation Procedures', 1;  
GO  
RECONFIGURE;  
GO
12
Andriy K