在 SQL Server(查询分析器)中的查询结果中识别隐藏字符的最佳方法是啥?
Posted
技术标签:
【中文标题】在 SQL Server(查询分析器)中的查询结果中识别隐藏字符的最佳方法是啥?【英文标题】:What's the best way to identify hidden characters in the result of a query in SQL Server (Query Analyzer)?在 SQL Server(查询分析器)中的查询结果中识别隐藏字符的最佳方法是什么? 【发布时间】:2012-01-29 03:59:04 【问题描述】:在尝试识别错误数据(通常需要手动查看和删除)时,我希望有一种简单的方法来查看隐藏字符,例如 TAB、空格、回车和换行。 有内置的方法吗?
在 *** 上的一个类似问题中,关于 Oracle,建议使用 DUMP(fieldname) 函数,但我不知道即使 SQL Server 中存在相应的函数,这是否会使事情变得更容易,因为我需要在他们的上下文中查看角色。
我能想到的最好的办法是用可见的字符替换预期的隐藏字符,如下所示:
SELECT REPLACE(REPLACE(REPLACE(REPLACE(myfield, ' ', '˙'), CHAR(13), '[CR]'), CHAR(10), '[LF]'), CHAR(9), '[TAB]') FROM mytable
有没有更好的方法?我不喜欢这种方式,因为我可能没有考虑其他不太常见的隐藏字符,例如垂直 TAB 等……打开“显示隐藏字符”,几乎可以在任何文本编辑器中执行,在 SQL Server 查询分析器中将是一个很好的功能,所以我几乎希望它也可以在 SQL Server 中以某种方式完成......或者至少有人有比我更好的想法来显示这种空白信息。
我刚刚注意到有一种查看“空白”的内置方法,不是在 SQL 查询分析器中,而是在曾经是 SQL Enterprise 管理器的界面部分中。右键单击 SQL Management Studio 对象资源管理器树中的表,然后选择“编辑前 200 行”。在结果中,空白(至少 CR LF)显示为空方块。
【问题讨论】:
你有一组有限的“好”字符吗?您可以使用 CLR 来使用 REGEX 替代品吗? 困难的部分是有时可以允许“坏”字符。这就是为什么我需要在他们的文本上下文中观察所有隐藏的字符。上面的 REPLACE 代码实际上实现了我目前所需要的(对于这个客户,我相当确定除了上面 Replace 中硬编码的那些空白字符之外没有其他空白字符),但我正在寻找一个更简单的,更全能的“显示隐藏字符”选项,适用于所有场合。 【参考方案1】:创建一个函数来处理所有可能的空白,并仅启用那些看起来合适的函数:
SELECT dbo.ShowWhiteSpace(myfield) from mytable
仅取消注释您要测试的那些空白案例:
CREATE FUNCTION dbo.ShowWhiteSpace (@str varchar(8000))
RETURNS varchar(8000)
AS
BEGIN
DECLARE @ShowWhiteSpace varchar(8000);
SET @ShowWhiteSpace = @str
SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(32), '[?]')
SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(13), '[CR]')
SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(10), '[LF]')
SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(9), '[TAB]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(1), '[SOH]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(2), '[STX]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(3), '[ETX]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(4), '[EOT]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(5), '[ENQ]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(6), '[ACK]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(7), '[BEL]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(8), '[BS]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(11), '[VT]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(12), '[FF]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(14), '[SO]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(15), '[SI]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(16), '[DLE]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(17), '[DC1]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(18), '[DC2]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(19), '[DC3]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(20), '[DC4]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(21), '[NAK]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(22), '[SYN]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(23), '[ETB]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(24), '[CAN]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(25), '[EM]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(26), '[SUB]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(27), '[ESC]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(28), '[FS]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(29), '[GS]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(30), '[RS]')
-- SET @ShowWhiteSpace = REPLACE( @ShowWhiteSpace, CHAR(31), '[US]')
RETURN(@ShowWhiteSpace)
END
【讨论】:
呃,这个支持character 202C吗?我猜不是。 您也应该包含 CHAR(0) [NUL]。【参考方案2】:我这样做的方法是选择所有数据
select * from myTable
然后右键单击结果集并选择“将结果另存为...”一个 csv 文件。
在 Notepad++ 中打开 csv 文件我看到 LF 字符在 SQL Server 结果集中不可见。
【讨论】:
最好的方法!只要确保你启用了换行 CRLF 可见【参考方案3】:要找到它们,您可以使用它
;WITH cte AS
(
SELECT 0 AS CharCode
UNION ALL
SELECT CharCode + 1 FROM cte WHERE CharCode <31
)
SELECT
*
FROM
mytable T
cross join cte
WHERE
EXISTS (SELECT *
FROM mytable Tx
WHERE Tx.PKCol = T.PKCol
AND
Tx.MyField LIKE '%' + CHAR(cte.CharCode) + '%'
)
用 JOIN 替换 EXISTS 将允许您替换它们,但您会得到多行...我想不出办法...
【讨论】:
啊,是的,这确实是查找低字符数字符的好方法! 这似乎不是有效的 SQL @paulwhit:以什么方式? 如果将其粘贴到 SQL Server Management Studio 中,它不会运行。它对 cte.Charcode 犹豫不决。如果我在子查询的 FROM 子句中包含 Tx, cte,它将运行,但我不确定它是否在做同样的事情。 已编辑以包括交叉连接 cte。这是一个非常有用的查询。【参考方案4】:您始终可以使用 DATALENGTH 函数来确定文本字段中是否有多余的空白字符。这不会使文本可见,但会告诉您哪里有多余的空白字符。
SELECT DATALENGTH('MyTextData ') AS BinaryLength, LEN('MyTextData ') AS TextLength
这将为 BinaryLength 生成 11,为 TextLength 生成 10。
在一个表中,您的 SQL 应该是这样的:
SELECT *
FROM tblA
WHERE DATALENGTH(MyTextField) > LEN(MyTextField)
此功能可用于从 2005 开始的所有 SQL Server 版本。
【讨论】:
仅供参考 - 这不适用于 NVARCHAR 字段。SELECT DATALENGTH(N'MyTextData ') AS BinaryLength, LEN(N'MyTextData ') AS TextLength
【参考方案5】:
select myfield, CAST(myfield as varbinary(max)) ...
【讨论】:
不符合“我需要在他们的上下文中查看角色”的要求。 顺便说一句,我没有更好的主意。除非有任何字体显示这些字形。 @oleg: varbinary这个东西大概是SQL Server相当于Oracle的DUMP功能,但是我在肉眼查看记录的时候找不到很好的利用方法。 @Martin Smith:用字形替代所有不可见字符的字体会很棒——然后我们就可以像在文本编辑器中一样查看结果——只是我不确定是否存在这样的字体。【参考方案6】:我遇到了同样的问题,我从未设法与 where 查询匹配的字符 - CHARINDEX, LIKE, REPLACE
等不起作用。然后我使用了一个很糟糕、很重但有效的蛮力解决方案:
第 1 步:制作完整数据集的副本 - 使用 source_id 引用源表的 pk 跟踪原始名称(并在所有后续表中保留此源 id) .
第 2 步:LTRIM RTRIM
数据,并将所有双空格、制表符等(基本上所有 CHAR(1) 到 CHAR(32) 都替换为一个空格。也将整个集合小写。
第 3 步:用 a-z 中的内容替换所有您知道的特殊字符(获取所有引号、双引号等的列表)(我建议使用 z)。基本上用 z 替换所有非标准英文字符(在循环中使用 REPLACE 的嵌套 REPLACE)。
第 4 步:按单词拆分为第二份副本,其中每个单词位于单独的行中 - 根据空格字符的位置拆分为 SUBSTRING
- 在这一点上,我们应该错过那些我们之前没有发现的隐藏空间。
第 5 步:将每个单词拆分为第三份副本,其中每个字母位于单独的行中(我知道它会构成一个非常大的表格) - 在单独的列中跟踪每个字母的 charindex。
第 6 步:选择上表中不是 LIKE [a-z] 的所有内容。这是我们要排除的未识别字符的列表。
从第 6 步的输出中,我们有足够的数据来制作一系列源的子字符串来选择除我们要排除的未知字符之外的所有内容。
注意 1:根据原始表达式的大小,有一些聪明的方法可以优化这一点(步骤 4、5 和 6 可以一次性完成)。
注意 2:这不是很快,但是对于大型数据集来说是最快的方法,因为将行拆分为单词和将单词拆分为字母是通过子字符串进行的,这将所有表切成一个字符切片。然而,这构建起来相当繁重。使用较小的集合,一个一个地解析每个记录并搜索不在所有英文字符和所有特殊字符的列表中的字符可能就足够了。
【讨论】:
以上是关于在 SQL Server(查询分析器)中的查询结果中识别隐藏字符的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章