Kornfeld Eliyahu Peter Ответов: 2

Делает ли SQL like likes NVARCHAR(MAX)?


Кажется, нет...

Представьте себе такой стол:
FORUM_MESSAGES (
  ID INT,
  COMMENT NVARCHAR(MAX)
)

Теперь смотрите этот запрос:
DECLARE @LIKE AS NVARCHAR(MAX) = NULL

SELECT
	*
FROM
	FORUM_MESSAGES
WHERE
	COMMENT LIKE ISNULL(@LIKE, COMMENT)

Если у вас есть комментарий длиной более 4000 букв, он будет отбрасывать ошибку усечения...
Глядя на план исполнения я обнаружил это небольшое изменение:
FORUM_MESSAGES.COMMENT like CONVERT_IMPLICIT(NVARCHAR(4000), ISNULL(@LIKE, FORUM_MESSAGES.COMMENT ), 0)

После некоторого копания стало очевидно, что оператор LIKE делает это с SQL...
Поискал в интернете, но не нашел подтверждения такого поведения...
У вас был какой-нибудь опыт работы с LIKE и NVARCHAR(MAX)?

[ОБНОВЛЕНИЕ]
Как очистить воздух после решения ОГА...
Я действительно понимаю, почему LIKE преобразуется... но есть проблема, что изменение @LIKE на NVACHAR(4000) не решает проблему...
В этом случае нет никакой ошибки усечения (даже SQL запускает CONVERT_IMPLICIT, теперь на комментарии), но строки с более чем 4000 буквами будут удалены без ошибок... Как-то это даже хуже, чем раньше, так как теперь ошибки нет, хотя явно есть усечение...

Что я уже пробовал:

Все, что в моих силах...
Поговорите с администратором...
Интенсивный Гугл...

На самом деле нашел несколько решений... но я ищу объяснение, почему SQL как будто заставляет меня опуститься до NVARCHAR(4000)...

Dave Kreskowiak

С какой стати вы используете подобное выражение с таким чертовски большим параметром?

Kornfeld Eliyahu Peter

Это своего рода наследство, которое я получил...
С ошибкой...
Часть моего решения-это отсутствие Макса...

Dave Kreskowiak

Ты унаследовал этот беспорядок? Я вам сочувствую. :)

Kornfeld Eliyahu Peter

Мой toooooooooo :-)

2 Ответов

Рейтинг:
2

OriginalGriff

Это есть в документации: LIKE (Transact-SQL) | Microsoft Docs[^]

Цитата:
Аргументы
match_expression
Является любым допустимым выражением символьного типа данных.

шаблон
Это конкретная строка символов для поиска в match_expression и может включать следующие допустимые символы подстановки. шаблон может быть не более 8000 байт.

Поскольку NVARCHAR использует 16-битные символы Unicode, это максимум 4000 символов.


Kornfeld Eliyahu Peter

Извините, но я не совсем ясно выразился...
Измените @LIKE на NVARCHAR(4000), и ошибка исчезнет, но виновник (запись с более чем 4000 буквами в комментарии) не будет показан...
Теперь SQL делает CONVERT_IMPLICIT на комментариях, но не все в порядке и нет ошибки усечения, но и записи тоже нет...

OriginalGriff

Это меня не очень удивляет: если комментарий содержит более 4000 символов и усекается неявным преобразованием, то если только 4000-й символ не является"%", шаблон не будет совпадать. У меня было бы искушение изменить все условия:

... WHERE @LIKE IS NULL OR Comment LIKE @LIKE

Kornfeld Eliyahu Peter

А то, что есть усечение (в конкретном случае вызванное ошибкой это усечение от 21000 до 4000) комментария, но ошибки нет, вас тоже не удивляет?

OriginalGriff

Нет, потому что нет никакой "потери данных", поскольку предложения WHERE ничего не меняют - и SQL не беспокоится о мелочах, если только это не может поставить под угрозу целостность. :смеяться:

Kornfeld Eliyahu Peter

Вот о чем я думал... Поскольку выражение, созданное усечением, не является частью результирующего набора, SQL это не волнует...

Kornfeld Eliyahu Peter

Я меняю линию вот так (я люблю ИСНУЛЛА без всякой причины):
ГДЕ КОММЕНТАРИЙ ТИПА ISNULL(@LIKE, '%')
А также изменил @LIKE на NVARCHAR(4000)...

OriginalGriff

Зачем тратить текстовый поиск, когда простое значение равно нулю быстрее?

Kornfeld Eliyahu Peter

Похоже, что SQL оптимизировал его в любом случае... в вашу пользу :-)

Рейтинг:
2

Jochen Arndt

Для LIKE (Transact-SQL) | Microsoft Docs[^] это задокументировано:

Цитата:
шаблон
Это конкретная строка символов для поиска в match_expression и может включать следующие допустимые символы подстановки. шаблон может быть не более 8000 байт.

Он может быть определен в официальном стандарте SQL. Поскольку вы должны платить за это, вы, вероятно, не нашли много в интернете.


Kornfeld Eliyahu Peter

См. комментарии для OG и обновление вопроса...

Jochen Arndt

Итак, вы используете T-SQL?
Потому что даже когда это определено стандартом, я предполагаю, что это специфично для поставщика базы данных; особенно поведение получения ошибки сейчас.

Kornfeld Eliyahu Peter

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

Jochen Arndt

Под провайдером я подразумеваю движок БД (T-SQL, MySQL, PostgreSQL), который может вести себя по-разному.

Я не ожидал, что существует опция конфигурации для таких ошибок.

В общем, мне очень жаль, что я больше ничем не могу помочь. Это может быть одна из тех проблем, которые не могут быть окончательно решены.

Kornfeld Eliyahu Peter

Я благодарю вас за любую помощь!!!
На самом деле проблема решена, но не объяснена полностью...