【问题标题】:Can you embed blob data in a script for sql server?您可以将 blob 数据嵌入到 sql server 的脚本中吗?
【发布时间】:2014-09-05 22:38:27
【问题描述】:

我正在测试 Web 应用程序对 blob 的检索。

从 javascript 代码以编程方式上传 blob 存在一些困难,因此我决定用一些数据预填充数据库。但是我也遇到了一些问题。

我们有一个数据库版本控制过程,它期望数据库的所有架构 + 数据都在可由 sqlcmd 运行的脚本中。

This post 似乎展示了如何插入 blob。但是,此脚本要求您指定服务器上文件的绝对路径。

还有其他方法吗?我们正在使用源代码控制和持续集成,因此我们不会真正想要在一台机器上的给定存储库副本之外的特定位置引用文件。

如果不是,似乎有 2 个选项:

接受打击,并且永远不要从数据库服务器上的随机目录中更改或删除任何内容。数据将需要在多个位置之间拆分。此外,我们要么禁止生产配置部署中的 blob,要么只需要记住,如果我们需要它们,我们必须做一些疯狂的事情——我们将无法控制远程服务器上的目录结构。公平地说,这可能不是一个大问题——我看不出我们真的想以 blob 形式发布任何配置。

或

编写一个程序来做一些疯狂的事情,比如在服务器上远程创建一个临时目录,然后将文件复制到正确的版本并输出一个带有该文件名的脚本。

将事物置于源代码控制之下并且不想对路径进行硬编码似乎确实是一种奇怪的情况,但是数据库工具的质量差不久前就不再让我感到惊讶了!

【问题讨论】:

    标签: sql-server blob


    【解决方案1】:

    假设您指的是 BINARY / VARBINARY / IMAGE 类型的字段,您应该能够只指定十六进制字节,例如:

    0x0012FD...
    

    例如:

    INSERT INTO TableName (IDField, BlobField) VALUES (1, 0x0012FD);
    

    您只需要从文件中获取该十六进制数字字符串。如果您已经在数据库中有这样的值,那么只需在 SSMS 中选择该行和字段,然后将单元格中的值(在“结果到网格”模式下)复制/粘贴到您的 SQL 脚本中。

    您还可以使用反斜杠将长行换行,如下所示:

    INSERT INTO TableName (IDField, BlobField) VALUES (1, 0x0012FD\
    12B36D98\
    D523);
    

    如果通过反斜杠换行,请确保在第一个位置开始每个新行,因为整个内容被视为连续字符串。因此,紧跟反斜杠的缩进行将在十六进制数字之间有空格,这是无效的。例如:

    INSERT INTO TableName (IDField, BlobField) VALUES (1, 0x0012FD\
      12B36D98\
    D523);
    

    等于:

    0x0012FD  12B36D98D523
    

    【讨论】:

    • 感谢我所希望的 + 又好又简单
    【解决方案2】:

    如果您可以访问 C#,这里有一个我使用过的函数,它将获取二进制 blob 并生成一个 SQL 脚本,该脚本将 varbinary(max) 变量设置为 blob 的内容。它将很好地格式化它并考虑到 SQL 语句的长度限制(这可能是非常大的 blob 的问题)。所以基本上它会输出如下内容:

    select @varname = 0x4d5a90000300000004000000ffff0000b8000000000000 +
    0x0040000000000000000000000000000000000000000000000000000000000000 +
    0x0000000000800000000e1fba0e00b409cd21b8014ccd21546869732070726f67 +
    ...
    0x007365745f4d6574686f64007365745f53656e644368756e6b65640053747265;
    select @varname = @varname + 0x616d004765745265717565737453747265 +
    0x616d0053797374656d2e5465787400456e636f64696e6700476574456e636f64 +
    ...
    

    您只需要确保在它提供给您的脚本前面声明变量。您可以构建一个小实用程序,在文件(或您的 blob 来自的任何地方)上运行此函数,以帮助创建脚本。

    public static string EncodeBinary(string variable, byte[] binary)
    {
        StringBuilder result;
        int column;
        int concats;
        bool newLine;
    
        if (binary.Length == 0)
        {
            return "select " + variable + " = null;";
        }
    
        result = new StringBuilder("select ");
        result.Append(variable);
        result.Append(" = 0x");
        column = 12 + variable.Length;
        concats = 0;
    
        for (int i = 0; i < binary.Length; i++)
        {
            newLine = false;
    
            if (column > 64)
            {
                concats++;
                newLine = true;
            }
    
            if (newLine)
            {
                if (concats == 64)
                {
                    result.Append(";\r\nselect ");
                    result.Append(variable);
                    result.Append(" = ");
                    result.Append(variable);
                    result.Append(" + 0x");
                    column = 15 + variable.Length * 2;
                    concats = 1;
                }
                else
                {
                    result.Append(" +\r\n0x");
                    column = 2;
                }
            }
    
            result.Append(binary[i].ToString("x2"));
            column += 2;
        }
    
        result.Append(";\r\n");
        return result.ToString();
    }
    

    【讨论】:

    • 很好 - 我真的很喜欢这种方法。对于我最初的需求来说,这有点矫枉过正,但如果你不得不做很多事情,它看起来正是要走的路
    猜你喜欢
    • 2020-05-27
    • 2016-11-16
    • 2010-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多