web-dev-qa-db-fra.com

moyen le plus rapide d'exporter des objets blob du tableau dans des fichiers individuels

Quel est le moyen le plus rapide d'exporter des fichiers (blobs) stockés dans une table SQL Server dans un fichier sur le disque dur? J'ai plus de 2,5 TB fichiers (90 kb moy) stockés en varbinary et je dois les extraire sur un disque dur local aussi rapidement que possible. BCP semble fonctionner mais il prendra le relais) 45 jours avec la vitesse que je vois et je crains que mon script échoue à un moment donné car Management Studio manquera de mémoire.

28
influent

J'ai essayé d'utiliser une fonction CLR et c'était plus de deux fois plus rapide que BCP. Voici mon code.

Méthode originale:

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

Méthode CLR:

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)

Code C # pour la fonction CLR

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

Je suis venu ici à la recherche d'exporter un blob dans un fichier avec le moins d'effort. Les fonctions CLR ne sont pas ce que j'appellerais le moins d'effort. Ici décrit un paresseux, en utilisant 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

Vous devrez peut-être autoriser l'exécution de procédures stockées OA sur le serveur (puis l'éteindre lorsque vous aurez terminé):

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