在此实时 SQL Server 2008(内部版本 10.0.1600)数据库中,有一个 Events
表,其中包含一个名为 Details
的 text
列。 (是的,我意识到这实际上应该是一个 varchar(MAX)
列,但是设置这个数据库的人并没有这样做。)
此列包含非常大的异常日志和我试图通过 SQL Server Management Studio 访问的相关 JSON 数据,但每当我将结果从网格复制到文本编辑器时,它都会将其截断为 43679 个字符。
我在 Internet 上的各个位置阅读过,您可以将 Tools > Options > Query Results > SQL Server > Results To Grid
中为 XML 数据检索的最大字符数设置为无限制,然后执行如下查询:
select Convert(xml, Details) from Events
where EventID = 13920
(请注意,数据是列根本不是 XML。CONVERT
将列转换为 XML 只是我从谷歌搜索中发现的一种解决方法,其他人用来绕过 SSMS 从 text
检索数据或varchar(MAX)
列。)
但是,在设置上述选项、运行查询并单击结果中的链接后,我仍然收到以下错误:
无法显示 XML。发生以下错误:出现意外的文件结尾。第 5 行,位置 220160。一种解决方案是增加从服务器检索到的 XML 数据的字符数。要更改此设置,请在工具菜单上单击选项。
那么,知道如何访问这些数据吗?将列转换为 varchar(MAX)
可以解决我的问题吗?
SSMS 仅允许 XML 数据的无限数据。这不是默认值,需要在选项中设置。
https://i.stack.imgur.com/QTBpg.png
在非常有限的情况下可能起作用的一个技巧是简单地以特殊方式命名列,如下所示,以便将其视为 XML 数据。
DECLARE @S varchar(max) = 'A'
SET @S = REPLICATE(@S,100000) + 'B'
SELECT @S as [XML_F52E2B61-18A1-11d1-B105-00805F49916B]
在 SSMS(至少 2012 版到当前的 18.3 版)中,显示结果如下
https://i.stack.imgur.com/BmUBv.png
单击它会在 XML 查看器中打开完整的结果。向右滚动显示 B 的最后一个字符被保留,
然而,这确实存在一些重大问题。向查询中添加额外的列会破坏效果,并且额外的行都会与第一行连接。最后,如果字符串包含诸如 <
之类的字符,则打开 XML 查看器会失败并出现解析错误。
避免 SQL Server 将 <
转换为 <
等问题或由于这些字符而失败的更可靠的方法如下 (credit Adam Machanic here)。
DECLARE @S varchar(max)
SELECT @S = ''
SELECT @S = @S + '
' + OBJECT_DEFINITION(OBJECT_ID) FROM SYS.PROCEDURES
SELECT @S AS [processing-instruction(x)] FOR XML PATH('')
我能够让它工作......
SELECT CAST('<![CDATA[' + LargeTextColumn + ']]>' AS XML) FROM TableName;
一种解决方法是右键单击结果集并选择“将结果另存为...”。这会将其导出到包含列的全部内容的 CSV 文件。不完美,但对我来说足够好。
https://i.stack.imgur.com/xeg3A.png
你试过这个简单的解决方案吗?只需点击 2 次即可!
在查询窗口中,
将查询选项设置为“结果到网格”,运行查询右键单击网格角的结果选项卡,将结果保存为任何文件
你会得到你想在文件中看到的所有文本!!!我可以看到 varchar(MAX) 字段的结果有 130,556 个字符
https://i.stack.imgur.com/fmDhS.jpg
我发现的最简单的解决方法是备份表并查看脚本。去做这个
右键单击您的数据库并选择 Tasks > Generate Scripts... “Introduction”页面单击 Next “Choose Objects”页面 选择 Select specific database objects 并选择您的表。单击下一步“设置脚本选项”页面 将输出类型设置为将脚本保存到特定位置 选择保存到文件并填写相关选项 单击高级按钮 将常规 > 要脚本的数据类型设置为仅数据或模式和数据并单击ok Click Next "Summary Page" click next 你的 sql 脚本应该是根据你在 4.2 中设置的选项生成的。打开此文件并查看您的数据。
数据类型 TEXT 已过时,不应再使用,从 TEXT 列中选择数据很痛苦。
ntext, text, and image (Transact-SQL)
在 Microsoft SQL Server 的未来版本中,将删除 ntext、text 和 image 数据类型。避免在新的开发工作中使用这些数据类型,并计划修改当前使用它们的应用程序。请改用 nvarchar(max)、varchar(max) 和 varbinary(max)。
您需要使用 TEXTPTR (Transact-SQL) 来检索文本数据。
另请参阅 Handling The Text Data Type 上的这篇文章。
varchar(MAX)
会阻止 SSMS 截断其中的数据吗?
听起来 Xml 可能格式不正确。如果是这种情况,那么您将无法将其转换为 Xml,并且鉴于此,您可以在 Management Studio 中返回多少文本是有限的。但是,您可以将文本分成更小的块,如下所示:
With Tally As
(
Select ROW_NUMBER() OVER ( ORDER BY s1.object_id ) - 1 As Num
From sys.sysobjects As s1
Cross Join sys.sysobjects As s2
)
Select Substring(T1.textCol, T2.Num * 8000 + 1, 8000)
From Table As T1
Cross Join Tally As T2
Where T2.Num <= Ceiling(Len(T1.textCol) / 8000)
Order By T2.Num
然后,您需要再次手动组合它们。
编辑
听起来 text
数据中有一些 Xml 解析器不喜欢的字符。您可以尝试将这些值转换为实体,然后尝试 Convert(xml, data)
技巧。所以像:
Update Table
Set Data = Replace(Cast(Data As varchar(max)),'<','<')
(我需要强制转换为 varchar(max),因为替换功能不适用于 text
列。应该没有任何理由不能将这些 text
列转换为 varchar(max)
。)
text
或 varchar(MAX)
列中检索数据的限制。
TSQL
对我来说效果很好。我基本上把结果(最终是 11 条记录)然后将它们粘贴到记事本中。工作完美。需要保存这个脚本。我有一些包含无效字符的疯狂长 XML。
我想你运气不好。这个问题不是所有其他答案似乎都关注的 SQL 级别问题,而只是用户界面之一。 Management Studio 并不是一个通用/通用数据访问接口。它不是你的界面,而是你的管理区域,它在处理二进制数据和大型测试数据方面有严重的限制——因为在指定的使用配置文件中使用它的人不会遇到这个问题。
呈现大文本数据根本不是计划的用途。
您唯一的选择是一个表值函数,它接受文本输入并为每一行剪切行,以便 Management Studio 获取行列表,而不是单行。
我更喜欢这种简单的 XML hack,它可以在 SSMS 中逐个单元格地点击列。使用此方法,您可以在 SSMS 的表格视图中快速查看数据,并在感兴趣的时候单击特定单元格以查看完整值。这与 OP 的技术相同,只是它避免了 XML 错误。
SELECT
e.EventID
,CAST(REPLACE(REPLACE(e.Details, '&', '&'), '<', '<') AS XML) Details
FROM Events e
WHERE 1=1
AND e.EventID BETWEEN 13920 AND 13930
;
NVARCHAR
/VARCHAR
中有效。例如,NUL 字符(不同于作为字段值的 NULL
)。对于具有此类嵌入值的字符串,强制转换将失败。
从 SSMS 18.2 开始,您现在可以在网格结果中查看多达 200 万个字符。 Source
允许显示更多数据(结果到文本)并存储在单元格中(结果到网格)。 SSMS 现在允许两者最多 2M 个字符。
我用下面的代码验证了这一点。
DECLARE @S varchar(max) = 'A'
SET @S = REPLICATE(@S,2000000) + 'B'
SELECT @S as a
CDATA
可能有效,但如果您的数据包含控制字符,则必须执行替换操作。就我而言,我在数据中使用了单位分隔符 ASCII 代码 31。因为我在很多地方只使用了那个字符,所以一个简单的REPLACE(details, char(31), '&x1f;')
就足够了。如果我有未知字符或大量不同的字符要替换,我可能不得不寻找另一种解决方案。CDATA
是我的第一个建议。AS [processing-instruction(x)]
的后一个避免了这种情况。