【问题标题】:How can I generate an INSERT script for a table with a VARBINARY(MAX) field?如何为具有 VARBINARY(MAX) 字段的表生成 INSERT 脚本?
【发布时间】:2011-04-12 03:13:07
【问题描述】:

我有一个带有VARBINARY(MAX) 字段的表(带有FILESTREAM 的SQL Server 2008)

我的要求是,当我去部署到生产环境时,我只能为我的 IT 团队提供一组 SQL 脚本,按一定的顺序执行。我在生产中制作的一张新表有这个VARBINARY(MAX) 字段。通常对于新表,我会编写 CREATE TABLE 脚本。而且,如果我有需要处理的数据,我将编写 INSERT 脚本。不太复杂。

但是对于VARBINARY(MAX),我用来生成INSERT 语句的存储过程在该表上失败了。我尝试选择该字段,打印它,复制它,转换为十六进制等。我遇到的主要问题是它没有选择该字段中的所有数据。我检查了DATALENGTH([FileColumn]),如果源行包含 1,004,382 字节,我在再次插入时可以获得复制或选择的数据的最大值是 8000。所以基本上它被截断(即无效)数据.....

我怎样才能做得更好?我像疯了一样尝试谷歌搜索,但我一定错过了一些东西。请记住,我无法访问文件系统。这必须全部编写脚本。

【问题讨论】:

    标签: sql-server tsql sql-server-2008 varbinary sqlfilestream


    【解决方案1】:

    如果这是一次性(或很少)要做的事情,您可以尝试按照此处所述从 SSMS 向导中编写数据脚本:

    http://sqlblog.com/blogs/eric_johnson/archive/2010/03/08/script-data-in-sql-server-2008.aspx

    或者,如果您需要经常执行此操作并希望将其自动化,您可以尝试SQL# SQLCLR 库(我编写的,虽然大部分是免费的,但您需要的功能不是)。执行此操作的函数是 DB_DumpData,它还会生成 INSERT 语句。

    但是,如果这是一次性或不经常执行的任务,请尝试使用 Management Studio 中内置的数据导出向导。这应该允许您创建可以在生产中运行的 SQL 脚本。我刚刚在一个表上进行了测试,该表的 VARBINARY(MAX) 字段包含 3,365,964 字节的数据,生成脚本向导生成了一个 INSERT 语句,其中包含 673 万个字符的整个十六进制字符串。

    更新:
    另一种快速简便的方法是,将整个 INSERT 语句复制/粘贴到 SQL 脚本中,而不必使用 BCP 或 SSMS 导出向导,只需将值转换为 XML。首先,您将 CONVERT VARBINARYVARCHAR(MAX) 使用可选样式“1”,它为您提供以“0x”开头的十六进制字符串。获得二进制数据的十六进制字符串后,您可以将其连接到 INSERT 语句中,当转换为 XML 时,整个内容可以包含整个 VARBINARY 字段。请参阅以下示例:

    DECLARE @Binary VARBINARY(MAX) = CONVERT(VARBINARY(MAX),
                                             REPLICATE(
                                               CONVERT(NVARCHAR(MAX), 'test string'),
                                               100000)
                                            )
    
    SELECT 'INSERT INTO dbo.TableName (ColumnName) VALUES ('+
           CONVERT(VARCHAR(MAX), @Binary, 1) + ')' AS [Insert]
    FOR XML RAW;
    

    【讨论】:

      【解决方案2】:

      不要从 SSMS 编写脚本

      bcp 输出/输入数据,或使用SSMS tools 之类的东西来生成 INSERT 语句

      【讨论】:

        【解决方案3】:

        这有点搞砸了,但在过去和网络上,我已经看到使用 base64 编码的字符串完成此操作。您使用 xml 值来包装字符串,然后您可以从那里将其转换为 varbinary。这是一个例子:
        http://blogs.msdn.com/b/sqltips/archive/2008/06/30/converting-from-base64-to-varbinary-and-vice-versa.aspx

        不过,我无法亲自谈论这有多有效或性能如何,尤其是对于大值而言。因为它充其量只是一个丑陋的 hack,我会把它藏在 UDF 的某个地方,这样如果找到更好的方法,你可以轻松地更新它。

        【讨论】:

          【解决方案4】:

          我以前从未尝试过这样的事情,但从 SQL Server 2008 R2 的文档来看,听起来使用 SUBSTRING 可以获取整个 varbinary 值,尽管您可能必须分块使用它,使用UPDATEs 使用 .WRITE 子句追加数据。

          更新大值数据类型

          使用 .WRITE(表达式、@Offset、@Length)子句对 varchar(max)、nvarchar(max) 和 varbinary(max) 数据类型执行部分或全部更新。例如,varchar(max) 列的部分更新可能只删除或修改该列的前 200 个字符,而完全更新将删除或修改该列中的所有数据。

          为获得最佳性能,我们建议以 8040 字节的倍数大小插入或更新数据。

          希望这会有所帮助。

          【讨论】:

          • 你能提供更多细节吗?感谢您迄今为止的所有帮助。
          • @Issa Fram,我不确定您是如何生成脚本的,但您可以尝试使用 SUBSTRINGDATALENGTH 来获取整个 varbinary 值。如果这有效并在您的脚本中生成了一个可用的插入语句,那么您就完成了。如果没有,您可以尝试使用循环来获取 varbinary 数据块(例如 8040 字节)并创建更新语句以将这些块写入目标行。但希望使用SUBSTRING 来获取整个值会起作用。
          猜你喜欢
          • 2020-03-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-26
          相关资源
          最近更新 更多