T SQL: кажущаяся пустой строка - PullRequest
0 голосов
/ 14 июля 2020

В рамках проекта хранилища данных Azure (выполняется на сервере Azure SQL), я реализую некоторые бизнес-логики c, чтобы добавить новое поле в измерение. Я обнаружил, что одно из моих полей для конкретной строки возвращает некоторые данные, которые мне трудно понять.

Столбец кажется, содержит пустую строку (т.е. ''), но на самом деле он не ловится при использовании функции REPLACE.

Вот мой код:

SELECT
    <MyColumn> as MyColumn
    , LEN (<MyColumn>)
    , REPLACE(<MyColumn> , '', 'foo')
    , ISNULL(<MyColumn> , 'bar')
    , UNICODE(<MyColumn>)
    , ASCII(<MyColumn>)
FROM 
    <MyTable>

И вывод в SSMS:

Вывод SSMS

Как видно, поле не содержит значение NULL или пустую строку, и ни одна из функций ASCII или UNICODE не возвращает допустимое значение. Я также попытался проверить наличие пробела (' '), но, увидев, что LEN() поля равно 0, это не сработало.

В итоге я решил обойти проблему, используя SELECT CASE WHEN LEN(<MyColumn>) = 0 THEN 'N/A' END , но мне любопытно, какая здесь ценность на самом деле. Есть идеи?

Спасибо!

Ответы [ 3 ]

2 голосов
/ 14 июля 2020

REPLACE(<MyColumn> , '', 'foo') ничего не сделает. REPLACE заменяет символы во втором параметре на символы в третьем. Ваш второй параметр представляет собой строку длины 0, поэтому не содержит символов для замены.

LEN не включает конечные пробелы, поэтому строка со значением ' ' вернет 0 для LEN . Если вы хотите включить конечные пробелы, используйте DATALENGTH. ЕСЛИ DATALENGTH(<MyColumn>) возвращает значение больше 0, оно содержит пробелы, если нет, то имеет значение ''. Использование NULLIF(<MyColumn>,'') также вернет NULL для любой строки с нулевой длиной или только содержащей пробелы.

Однако тот факт, что и UNICODE, и ASCII return NULL предполагает, что столбец имеет значение '', поскольку строка нулевой длины не может иметь значение ASCII / UNICODE. Это может быть подтверждено приведенными ниже примерами данных:

SELECT V.YourString,
       V.StringDescription,
       LEN(V.YourString) AS StringLEN, --Will return 0 for all rows
       DATALENGTH(V.YourString) AS StringDATALENGTH, --Will return varying results,
       REPLACE(V.YourString, '', 'foo') AS StringREPLACEBlank, --Will do nothing, there are no characters to replace
       REPLACE(V.YourString, ' ', 'foo') AS StringREPLACEWhiteSpace, --Varying lengths of foo
       ASCII(V.YourString) AS StringASCII, --Will return NULL for Empty String
       NULLIF(V.YourString,'') AS StringNULLIF --Will return NULL for Empty String
FROM (VALUES('','Empty String'),
            (' ','One White Space'),
            ('   ','Multiple White Space'))V(YourString, StringDescription)

, который возвращает следующий набор данных:

YourString StringDescription    StringLEN   StringDATALENGTH StringREPLACEBlank StringREPLACEWhiteSpace StringASCII StringNULLIF
---------- -------------------- ----------- ---------------- ------------------ ----------------------- ----------- ------------
           Empty String         0           0                                                           NULL        NULL
           One White Space      0           1                                   foo                     32          NULL
           Multiple White Space 0           3                                   foofoofoo               32          NULL

Причина NULLIF(Column,'') возвращает NULL для обоих нулей строки длины и строки, содержащие только пробелы, потому что это сокращенное выражение CASE. NULLIF(Column,'') разбирается как CASE WHEN Column = '' THEN NULL ELSE Column END. При сравнении строк с оператором = строка с конечными пробелами по сравнению со строкой без них будет рассматриваться как одно и то же значение. Например, ' ' = '' будет правдой. Это означает, что если Column имеет значение ' ', то Column = '' также будет True, а NULL будет возвращено NULLIF.

2 голосов
/ 14 июля 2020

REPLACE ищет подстроку в исходной строке. Поскольку вы ничего не ищете, ничего не заменяется.

Более подробную информацию можно найти здесь: https://www.w3schools.com/sql/func_sqlserver_replace.asp

0 голосов
/ 14 июля 2020

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

Однако есть много разных «невидимых» символов, другие чем космос. Вы можете попробовать скопировать и вставить его на веб-сайт, который может идентифицировать символы Юникода (например, этот ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...