Как лучше всего определить скрытые символы в результате запроса в SQL Server (Query Analyzer)? - PullRequest
33 голосов
/ 28 декабря 2011

При попытке идентифицировать ошибочные данные (часто требующие ручного просмотра и удаления), мне нужен простой способ увидеть скрытые символы, такие как TAB, пробел, возврат каретки и перевод строки. Есть ли встроенный способ для этого?

В аналогичном вопросе здесь о stackoverflow, касающемся Oracle, была предложена функция DUMP (fieldname), но я не знаю, может ли это сделать проще, даже если соответствующая функция будет существовать в SQL Server, так как мне нужно увидеть персонажей в их контексте.

Лучшая идея, которую я мог придумать, - заменить ожидаемые скрытые символы видимыми, например:

SELECT REPLACE(REPLACE(REPLACE(REPLACE(myfield, ' ', '˙'), CHAR(13), '[CR]'), CHAR(10), '[LF]'), CHAR(9), '[TAB]') FROM mytable

Есть ли лучший способ? Мне не нравится этот способ, так как могут быть другие менее распространенные скрытые символы, которые я не учитываю, такие как вертикальная вкладка и т. Д. Включение «показывать скрытые символы», как вы можете сделать почти в любом текстовом редакторе, было бы такой хорошей функцией в SQL Server Query Analyzer, так что я почти ожидаю, что это можно сделать как-то и на SQL-сервере ... или, по крайней мере, у кого-то есть идея даже лучше, чем у меня, чтобы показать этот вид пробела Информация.

Я только что заметил, что есть встроенный способ просмотра «пробелов» не в SQL Query Analyzer, а в той части интерфейса, которая когда-то была менеджером SQL Enterprise. Щелкните правой кнопкой мыши таблицу в дереве обозревателя объектов SQL Management Studio и выберите «Редактировать 200 верхних строк». В результате пробел (по крайней мере, CR LF) виден как пустые квадраты.

Ответы [ 6 ]

47 голосов
/ 28 декабря 2011

Создайте функцию, которая обращается ко всем возможным пробелам и включите только те, которые кажутся подходящими:

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
9 голосов
/ 28 декабря 2011

Чтобы найти их, вы можете использовать это

;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) + '%'
         )

Замена EXISTS на JOIN позволит вам ЗАМЕНИТЬ их, но вы получите несколько строк ... Я не могу думать ообойти это ...

8 голосов
/ 05 марта 2014

Они так и сделали, выбрав все данные

select * from myTable, а затем щелкните правой кнопкой мыши набор результатов и выберите «Сохранить результаты как ...» в CSV-файле.

Открытие csv-файла в Notepad ++ Я видел символы LF, не видимые в наборе результатов SQL Server.

5 голосов
/ 14 сентября 2017

Вы всегда можете использовать функцию DATALENGTH, чтобы определить, есть ли у вас дополнительные пробельные символы в текстовых полях. Это не сделает текст видимым, но покажет вам, где есть лишние пробелы.

    SELECT DATALENGTH('MyTextData ') AS BinaryLength, LEN('MyTextData ') AS TextLength

Это даст 11 для BinaryLength и 10 для TextLength.

В таблице ваш SQL будет выглядеть так:

    SELECT * 
    FROM tblA
    WHERE DATALENGTH(MyTextField) > LEN(MyTextField)

Эта функция доступна во всех версиях SQL Server, начиная с 2005 года.

0 голосов
/ 16 января 2018

Я столкнулся с той же проблемой с символом, который мне никогда не удавалось сопоставить с запросом where - CHARINDEX, LIKE, REPLACE и т. Д. Не работали. Тогда я использовал решение грубой силы, которое ужасно, тяжело, но работает:

Шаг 1 : сделать копию полного набора данных - отслеживать исходные имена с помощью source_id, ссылающегося на pk исходной таблицы (и сохранять этот идентификатор источника во всех последующих таблицах). Шаг 2 : LTRIM RTRIM данных и замените все двойные пробелы, табуляцию и т. Д. (В основном все символы CHAR (1) - CHAR (32) одним пробелом). Шаг 3 : заменить все известные вам специальные символы (получить список всех кавычек, двойных кавычек и т. Д.) Чем-то из a-z (я предлагаю z). В основном замените все, что не является стандартными английскими символами, на z (используя вложенный REPLACE of REPLACE в цикле). Шаг 4 : разделить слово на вторую копию, где каждое слово находится в отдельной строке - разделение равно SUBSTRING в зависимости от положения символов пробела - в этот момент мы должны пропустить те, где есть скрытое пространство, которое мы не поймали ранее. Шаг 5 : разбить каждое слово на третью копию, где каждая буква находится в отдельной строке (я знаю, что это очень большая таблица) - отслеживать хариндекс каждой буквы в отдельном столбце. Шаг 6 : Выберите в таблице выше все, что не похоже на [A-z]. Это список неопознанных символов, которые мы хотим исключить.

Из выходных данных шага 6 у нас достаточно данных, чтобы сделать серию подстрок источника, чтобы выбрать все, кроме неизвестного символа, который мы хотим исключить.

Примечание 1 : есть разумные способы оптимизировать это, в зависимости от размера исходного выражения (шаги 4, 5 и 6 могут быть выполнены за один раз).

Примечание 2 : это не очень быстро, но самый быстрый способ сделать это для большого набора данных, потому что разбиение строк на слова и слова на буквы производится подстрокой, которая разрезает все таблицы в один ломтик символа. Тем не менее, это довольно тяжело построить. При меньшем наборе может быть достаточно проанализировать каждую запись одну за другой и найти символ, которого нет в списке всех английских символов плюс все специальные символы.

0 голосов
/ 28 декабря 2011
select myfield, CAST(myfield as varbinary(max)) ...
...