你能在sql server的脚本中嵌入blob数据吗?

时间:2014-07-15 16:15:02

标签: sql-server blob

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

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

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

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

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

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

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

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

看起来似乎没有源代码控制的东西,并且不想硬编码路径,这完全是一个古怪的场景,但数据库工具质量差,不久前让我感到惊讶!

2 个答案:

答案 0 :(得分:2)

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

0x0012FD...

例如:

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

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

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

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

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

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

等同于:

0x0012FD  12B36D98D523

答案 1 :(得分:1)

如果您可以访问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();
}