Basic info on how to export BLOB as files

半世苍凉 提交于 2021-01-08 06:06:30

问题


I have researched on how to export BLOBs to image. A DB has an IMAGE column storing several thousand images. I thought of exporting the table but I get a BLOB file error in EMS SQL Manager for InterBase and Firebird.

There have been good posts, but I have still not been able to succeed.

  1. SQL scripts to insert File to BLOB field and export BLOB to File

    This example has appeared on numerous pages, including Microsoft's site. I am using INTERBASE (Firebird). I have not found anything related to enabling xp_shell for Firebird, or EMS SQL Manager for InterBase and Firebird (which I have also installed). My guess is: its not possible. I also tried Installing SQL Server Express, SQL Server 2008, and SQL Server 2012. I am at a dead end without having even connected to the server. The reason being I have not managed to start the server. Followed the guide at technet.microsoft: How to: Start SQL Server Agent but there are no services on the right pane to me.

  2. PHP file to download entire column (may not post link due to rep limitation).

    It has a MySQL connect section that daunts me. There on my computer is the DB as a GDB file, I also have XAMPP. I can figure out a way to use this as a localhost environment. I hope this is making sense.

  3. Last solution is to use bcp, an idea posted on Stack Overflow titled: fastest way to export blobs from table into individual files. I read the documentation, installed it, but cannot connect to server. I use -S PC-PC -U xxx -P xxx (The server must be wrong) But the information I find all uses -T (Windows Authentication)

Summing up. I am using Firebird, as EMS SQL Manager. I try to extract all images from images table into individual files. These tools both have SQL script screens, but it appears to be in conjunction with xp shell. What would you suggest? Am I using the wrong SQL manager to accomplish this?


回答1:


There are several ways:

  • Use isql command BLOBDUMP to write a blob to file,
  • Use a client library (eg Jaybird for Java, Firebird .net provider for C#) to retrieve the data,
  • With PHP you can use ibase_blob_get in a loop to get bytes from the blob, and write those to a file.

I don't use nor know EMS SQL Manager, so I don't know if (and how) you can export a blob with that.

The example you link to, and almost all tools you mention are for Microsoft SQL Server, not for Firebird; so it is no wonder those don't work.

Example in Java

A basic example to save blobs to disk using Java 8 (might also work on Java 7) would be:

/**
 * Example to save images to disk from a Firebird database.
 * <p>
 * Code assumes a table with the following structure:
 * <pre>
 * CREATE TABLE imagestorage (
 *     filename VARCHAR(255),
 *     filedata BLOB SUB_TYPE BINARY
 * );
 * </pre>
 * </p>
 */
public class StoreImages {
    // Replace testdatabase with alias or path of database
    private static final String URL = "jdbc:firebirdsql://localhost/testdatabase?charSet=utf-8";
    private static final String USER = "sysdba";
    private static final String PASSWORD = "masterkey";
    private static final String DEFAULT_FOLDER = "D:\\Temp\\target";

    private final Path targetFolder;

    public StoreImages(String targetFolder) {
        this.targetFolder = Paths.get(targetFolder);
    }

    public static void main(String[] args) throws IOException, SQLException {
        final String targetFolder = args.length == 0 ? DEFAULT_FOLDER : args[0];
        final StoreImages storeImages = new StoreImages(targetFolder);
        storeImages.store();
    }

    private void store() throws IOException, SQLException {
        if (!Files.isDirectory(targetFolder)) {
            throw new FileNotFoundException(String.format("The folder %s does not exist", targetFolder));
        }
        try (
            Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
            Statement stmt = connection.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT filename, filedata FROM imagestorage")
        ) {
            while (rs.next()) {
                final Path targetFile = targetFolder.resolve(rs.getString("FILENAME"));
                if (Files.exists(targetFile)) {
                    System.out.printf("File %s already exists%n", targetFile);
                    continue;
                }
                try (InputStream data = rs.getBinaryStream("FILEDATA")) {
                    Files.copy(data, targetFile);
                }
            }
        }
    }
}

Example in C#

Below is an example in C#, it is similar to the code above.

class StoreImages
{
    private const string DEFAULT_FOLDER = @"D:\Temp\target";
    private const string DATABASE = @"D:\Data\db\fb3\fb3testdatabase.fdb";
    private const string USER = "sysdba";
    private const string PASSWORD = "masterkey";

    private readonly string targetFolder;
    private readonly string connectionString;

    public StoreImages(string targetFolder)
    {
        this.targetFolder = targetFolder;
        connectionString = new FbConnectionStringBuilder
        {
            Database = DATABASE,
            UserID = USER,
            Password = PASSWORD
        }.ToString();
    }

    static void Main(string[] args)
    {
        string targetFolder = args.Length == 0 ? DEFAULT_FOLDER : args[0];
        var storeImages = new StoreImages(targetFolder);
        storeImages.store();
    }

    private void store()
    {
        if (!Directory.Exists(targetFolder))
        {
            throw new FileNotFoundException(string.Format("The folder {0} does not exist", targetFolder), targetFolder);
        }
        using (var connection = new FbConnection(connectionString))
        {
            connection.Open();
            using (var command = new FbCommand("SELECT filename, filedata FROM imagestorage", connection))
            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    string targetFile = Path.Combine(targetFolder, reader["FILENAME"].ToString());
                    if (File.Exists(targetFile))
                    {
                        Console.WriteLine("File {0} already exists", targetFile);
                        continue;
                    }

                    using (var fs = new FileStream(targetFile, FileMode.Create))
                    {
                        byte[] filedata = (byte[]) reader["FILEDATA"];
                        fs.Write(filedata, 0, filedata.Length);
                    }
                }
            }
        }
    }
}


来源:https://stackoverflow.com/questions/29212166/basic-info-on-how-to-export-blob-as-files

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!