如何在SSMS中检索非常长的varcharmax的值作为文本

时间:2015-06-25 16:30:00

标签: sql-server xml file tsql varchar

我找不到这个问题的确切解决方案。我有一个SQL脚本,可以在不同的步骤中创建另一个非常长的脚本。

我所做的是,在脚本中,使用连接将新脚本添加到varchar(max)。最后的剧本很长,以至于我很难掌握它。我使用以下作为最终指令:

SELECT [processing-instruction(x)] = @MyScript 
FOR XML PATH(''), TYPE;

通过这种方式,我可以设法获得相当长的结果,但有时候结果很长,看起来SSMS内存不足。

我尝试通过选择保存变量@MyScript并将结果保存为文本或文件,但保存的字符少于20K。我已将XML最大输出长度设置为无限制,它似乎可以工作,但是当我点击带有蓝色内容的结果单元格(带脚本的xml)时,SSMS会冻结。

好处是,APPEARENTLY脚本生成速度非常快(我正在使用打印记录不同的步骤),但我无法看到我的努力结果。

有什么方法可以抓住这个冗长的varchar(max)的内容吗?

由于

3 个答案:

答案 0 :(得分:0)

创建一个选择变量作为输出的过程。

SELECT @MyScript XmlData
FOR XML PATH(''), TYPE;

然后转到命令行并执行:

bcp "exec sp_OutputXml" queryout MyScript.xml -w -T -S <server> -d <database>

如果您想使用T-SQL完成所有操作,则可以使用xp_cmdshell运行bcp命令(如果已在服务器上启用了该命令)。

答案 1 :(得分:0)

如果要将MAX类型变量或字段(VARCHAR(MAX)NVARCHAR(MAX)VARBINARY(MAX) - 的内容保存到文件中,可以创建SQLCLR存储过程或函数(我会选择函数,以便它可以在查询中内联使用,以保存字段的内容,而无需先将其转移到变量,更不用说基于集合和所有)。

为了保存字符串,你可以放弃做一些像File.WriteAllText这样简单的事情。有点像:

C#代码:

using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.IO;

public class SaveStuff
{
  [SqlFunction(IsDeterministic = false, IsPrecise = true)]
  public static SqlInt32 SaveToFile([SqlFacet(MaxSize = 500)] SqlString FilePath,
      [SqlFacet(MaxSize = -1)] SqlString TextToSave)
  {
      File.WriteAllText(FilePath.Value, TextToSave.Value);

      return TextToSave.Value.Length;
  }
}

请注意:

  • 由于访问文件系统,程序集需要在PERMISSION_SET = EXTERNAL_ACCESS注册。虽然将数据库设置为TRUSTWORTHY ON更容易,但最好是:
    • 签署程序集并使用密码来保护密钥文件。
    • 从DLL创建非对称密钥
    • 从该非对称密钥创建登录
    • 授予登录EXTERNAL ACCESS ASSEMBLY权限
  • 上面的代码使用系统默认编码,该编码可能与SQL Server中字符串的编码方式相匹配,也可能不匹配。如有必要,还有另一个File.WriteAllText重载,它接受第三个输入参数来设置编码。
  • 上面的C#代码不测试.IsNull的任何输入参数,因为最好使用WITH RETURNS NULL ON NULL INPUT创建T-SQL包装器对象,因为如果任一输入参数为{{},它会完全跳过调用此方法{1}}。

测试查询:

NULL

在我的慢速笔记本电脑上,它导出了23.8 MB(25,000,000字节):

  

CPU时间= 94 ms,经过时间= 188 ms。

并向DECLARE @Bob NVARCHAR(MAX); SET @Bob = REPLICATE(CONVERT(NVARCHAR(MAX), N'This is just a test, yo! '), 1000000); SELECT LEN(@Bob); -- 25,000,000 SET STATISTICS TIME ON; SELECT dbo.SaveToFile(N'C:\TEMP\StackOverflow\z.txt', @Bob); -- 25,000,000 SET STATISTICS TIME OFF; 函数添加0,导出238 MB(250,000,000字节):

  

CPU时间= 1704 ms,经过时间= 8714 ms。

(总经过时间为33秒,因此需要24秒才能生成要保存的值)

现在,如果你不想搞乱创建SQLCLR程序集和非对称密钥等,这个函数(名为REPLICATE)和许多其他函数(包括File_WriteFile)都是可在SQL#库(我是其作者)中找到。请注意,File_WriteFileBinary功能仅在完整版中提供,而不是在免费版中。

答案 2 :(得分:0)

另一个避免SSMS处理大变量的全部内容的选项是让SQL Server通过电子邮件将该变量的内容作为SQL脚本发送给您。类似的东西:

sp_send_dbmail @query = 'SELECT @MyScript AS [--MyScript]',
               @recipients = 'your@email.address',
               @subject = 'My SQL Script',
               @attach_query_result_as_file = 1,
               @query_attachment_filename = 'DoLotsOfThings.sql',
               @query_no_truncate = 1;

请注意,默认的最大文件附件大小为1 MB。我不确定该限制是否适用于作为文件附加的查询结果,因此可能需要首先运行以下内容来增加该限制:

sysmail_configure_sp 'MaxFileSize', '52428800'; -- set Max to 50 MB

更多信息: