有关如何将 BLOB 导出为文件的基本信息

Basic info on how to export BLOB as files

我研究了如何将 BLOB 导出到图像。一个数据库有一个 IMAGE 列存储几千张图片。我想导出 table 但我在 EMS SQL InterBase 和 Firebird 的管理器 中收到 BLOB 文件错误。

有过不错的post,但我还是没能成功。

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

    这个例子出现在很多页面上,包括微软的网站。我正在使用 INTERBASE(Firebird)。我没有发现任何与为 Firebird 启用 xp_shell 或为 InterBase 和 Firebird(我也安装了)启用 EMS SQL Manager 相关的内容。我的猜测是:这不可能。我还尝试安装 SQL Server Express、SQL Server 2008 和 SQL Server 2012。我什至没有连接到服务器就走投无路了。原因是我没有设法启动服务器。按照 technet.microsoft 的指南进行操作:How to: Start SQL Server Agent 但右侧窗格中没有任何服务给我。

  2. PHP 文件下载整个专栏(由于代表限制,可能不会 post link)。

    它有一个 MySQL 连接部分让我望而却步。我的电脑上有 GDB 文件形式的数据库,我也有 XAMPP。我可以想出一种将其用作本地主机环境的方法。我希望这是有道理的。

  3. 最后的解决方案是使用 bcp,Stack Overflow 上的一个想法 post 标题为:将 blob 从 table 导出到单个文件的最快方法。我阅读了文档并安装了它,但无法连接到服务器。我用的是-S PC-PC -U xxx -P xxx(肯定是服务器错了)但是我查到的信息都是用的-T(Windows认证)

总结一下。我正在使用 Firebird,作为 EMS SQL Manager。我尝试将图像 table 中的所有图像提取到单个文件中。这些工具都有 SQL 脚本屏幕,但它似乎与 xp shell 结合使用。你有什么建议?我是否使用了错误的 SQL 经理来完成此任务?

有几种方法:

  • 使用 isql 命令 BLOBDUMP 将 blob 写入文件,
  • 使用客户端库(例如 Java 的 Jaybird,C# 的 Firebird .net 提供程序)检索数据,
  • 使用 PHP,您可以在循环中使用 ibase_blob_get 从 blob 中获取字节,并将它们写入文件。

我既不使用也不了解 EMS SQL 管理器,所以我不知道您是否(以及如何)使用它导出 blob。

您 link 的示例以及您提到的几乎所有工具都是针对 Microsoft SQL Server 的,而不是针对 Firebird 的;所以难怪那些不起作用。

Java

中的示例

使用 Java 8(也可能适用于 Java 7)将 blob 保存到磁盘的基本示例是:

/**
 * 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);
                }
            }
        }
    }
}

C# 示例

下面是一个C#的例子,和上面的代码类似。

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);
                    }
                }
            }
        }
    }
}