Пустая строка SQL Server 2008 года по сравнению с пространством

Google в конечном счете придумал ответ. Синтаксис для строковой замены в пакете - это:

set v_myvar=replace me
set v_myvar=%v_myvar:ace=icate%

, Который производит, "копируют меня". Мой сценарий теперь похож на это:

@echo off
set v_params=%*
set v_params=%v_params:"=\"%
call bash -c "g++-linux-4.1 %v_params%"

то, Которое заменяет все экземпляры " с \", правильно вышло для удара.

80
задан Bridge 7 September 2016 в 15:45
поделиться

4 ответа

varchar и равенство в TSQL непросто. Функция LEN говорит:

Возвращает количество символов, а не количество байтов заданного строкового выражения, , исключая завершающие пробелы .

Вам необходимо использовать DATALENGTH для получения истинного байтового счетчика рассматриваемых данных. Если у вас есть данные в формате Unicode, обратите внимание, что значение, которое вы получите в этой ситуации, не будет совпадать с длиной текста.

print(DATALENGTH(' ')) --1
print(LEN(' '))        --0

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

  • ] Получить более короткую строку
  • Заполнить пробелами до тех пор, пока длина не станет равной длине более длинной строки
  • Сравните два

Это средний шаг, который приводит к неожиданным результатам - после этого шага, вы эффективно сравниваете пробелы с пробелами - следовательно, они кажутся равными.

LIKE ведет себя лучше, чем = в ситуации с «пробелами», потому что он не выполняет заполнение пробелами для шаблон, который вы пытались сопоставить:

if '' = ' '
print 'eq'
else
print 'ne'

даст eq , а:

if '' LIKE ' '
print 'eq'
else
print 'ne'

даст ne

Осторожно с LIKE , хотя: он не симметричен: он обрабатывает завершающие пробелы как значимые в шаблоне (RHS), но не в выражении соответствия (LHS). Следующее взято из здесь :

declare @Space nvarchar(10)
declare @Space2 nvarchar(10)

set @Space = ''
set @Space2 = ' '

if @Space like @Space2
print '@Space Like @Space2'
else
print '@Space Not Like @Space2'

if @Space2 like @Space
print '@Space2 Like @Space'
else
print '@Space2 Not Like @Space'

@Space Not Like @Space2
@Space2 Like @Space
83
ответ дан 24 November 2019 в 09:59
поделиться

Оператор = в T-SQL не столько "равно", сколько "являются одним и тем же словом / фразой в соответствии с сопоставлением контекста выражения", а LEN - " количество символов в слове / фразе. " Никакие параметры сортировки не рассматривают завершающие пробелы как часть предшествующего им слова / фразы (хотя они рассматривают начальные пробелы как часть предшествующей им строки).

Если вам нужно отличать «это» от «это», вам не следует используйте оператор «одно и то же слово или фраза», потому что «это» и «это» - одно и то же слово.

Способ = работает идея о том, что оператор равенства строк должен зависеть от содержимого своих аргументов и от контекста сопоставления выражения, но он не должен зависеть от типов аргументов, если они оба являются строковыми типами.

Понятие «это одно и то же слово» в естественном языке обычно недостаточно точное, чтобы его можно было уловить математическим оператором, таким как =, и нет понятия строкового типа в естественном язык. Контекст (то есть сопоставление) имеет значение (и существует на естественном языке) и является частью истории, а дополнительные свойства (некоторые, которые кажутся причудливыми) являются частью определения =, чтобы сделать его четко определенным в неестественном мире data.

Что касается типа, вам не нужно, чтобы слова изменялись, когда они хранятся в строках разных типов. Например, типы VARCHAR (10), CHAR (10) и CHAR (3) могут содержать представления слова «кошка» и? = 'cat' должно позволить нам решить, содержит ли значение любого из этих типов слово 'cat' (с проблемами регистра и акцента, определяемыми сопоставлением.)

Ответ на комментарий JohnFx:

См. Использование данных char и varchar в электронной документации. Цитата с этой страницы, выделено мной:

Каждое значение данных char и varchar имеет сопоставление. Сопоставления определяют атрибуты, такие как битовые шаблоны, используемые для представления каждого символа, правила сравнения и чувствительность к регистру или акценту.

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

Также стоит отметить семантику SQL, где = должен делать с реальными данными и контекстом сравнения (в отличие от чего-то, что связано с битами, хранящимися на компьютере) долгое время являлся частью SQL. Предпосылкой для СУБД и SQL является точное представление реальных данных, поэтому они поддерживают сопоставления за много лет до того, как аналогичные идеи (такие как CultureInfo) вошли в сферу алголо-подобных языков. Предпосылка этих языков (по крайней мере, до недавнего времени) заключалась в решении инженерных проблем, а не в управлении бизнес-данными. (В последнее время использование подобных языков в не инженерных приложениях, таких как поиск, набирает обороты, но Java, C #, и так далее, все еще борются со своими неделовыми корнями.)

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

Черт возьми, когда SQL был впервые указан, некоторые языки не имели встроенных средств. в строковом типе. И в некоторых языках по-прежнему оператор равенства между строками вообще не сравнивает символьные данные, а сравнивает ссылки! Меня не удивит, если через десять или два десятилетия идея, что == зависит от культуры, станет нормой.

SQL был разработан для поддержки структуры для моделирования бизнес-данных, которая сильно отличается от инженерной, поэтому язык другой (и лучше для его цели).

Черт возьми, когда SQL был впервые указан, некоторые языки не имели встроенных средств. в строковом типе. И в некоторых языках по-прежнему оператор равенства между строками вообще не сравнивает символьные данные, а сравнивает ссылки! Меня не удивит, если через десять или два десятилетия идея, что == зависит от культуры, станет нормой.

SQL был разработан для поддержки структуры для моделирования бизнес-данных, которая сильно отличается от инженерной, поэтому язык другой (и лучше для его цели).

Черт возьми, когда SQL был впервые указан, некоторые языки не имели встроенных средств. в строковом типе. И в некоторых языках по-прежнему оператор равенства между строками вообще не сравнивает символьные данные, а сравнивает ссылки! Меня не удивит, если через десять или два десятилетия идея, что == зависит от культуры, станет нормой.

t вообще сравнивать символьные данные, но сравнивать ссылки! Меня не удивит, если через десять или два десятилетия идея, что == зависит от культуры, станет нормой.

t вообще сравнивать символьные данные, но сравнивать ссылки! Меня не удивит, если через десять или два десятилетия идея, что == зависит от культуры, станет нормой.

18
ответ дан 24 November 2019 в 09:59
поделиться

Я нашел эту статью в блоге , в которой описывается поведение и объясняется, почему.

Стандарт SQL требует этой строки сравнения, эффективно дополнять более короткая строка с пробелами. Это приводит к удивительному результату что N '' = N '' (пустая строка равно строке из одного или нескольких пробелов символы) и вообще любые строка равна другой строке, если они отличаются только конечными пробелами. Эта может быть проблемой в некоторых контекстах.

Дополнительная информация также доступна в MSKB316626

9
ответ дан 24 November 2019 в 09:59
поделиться

There was a similar question a while ago where I looked into a similar problem here

Instead of LEN(' '), use DATALENGTH(' ') - that gives you the correct value.

The solutions were to use a LIKE clause as explained in my answer in there, and/or include a 2nd condition in the WHERE clause to check DATALENGTH too.

Have a read of that question and links in there.

5
ответ дан 24 November 2019 в 09:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: