Прочитав это ограничение длины символа LIKE здесь, похоже, что я не могу отправить текст длиной более ~ 4000 символов в предложении LIKE.
Я пытаюсь получить план запроса из кэша плана запроса для конкретного запроса.
SELECT *
FROM sys.dm_exec_cached_plans AS cp
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) AS qp
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) AS st
where st.text like '%MY_QUERY_LONGER_THAN_4000_CHARS%' ESCAPE '?'
если запрос внутри LIKE
переменной длиннее 4000 символов, я получаю 0 результатов, даже если мой запрос находится в плане кэширования. (Я ожидал, по крайней мере, erorr).
Есть ли способ обойти эту проблему или сделать это по-другому? У меня есть запросы, которые могут быть 10000
длиной > символов, и похоже, что я не могу найти их с помощью LIKE
.
sql-server
t-sql
sql-server-2016
like
Дан Дину
источник
источник
where st.text like '%MY_QUERY%CHARS%' ESCAPE '?'
Ответы:
Похоже, что это не может быть решено в чистом T-SQL, так как не позволяет и
CHARINDEX
неPATINDEX
позволяет использовать более 8000 байтов в строке «для поиска» (т. Е. Не более 8000VARCHAR
или 4000NVARCHAR
символов). Это можно увидеть в следующих тестах:Оба этих запроса возвращают следующую ошибку:
И, уменьшая
7000
в любом из этих запросов, чтобы3999
избавиться от ошибки. Значение4000
в обоих случаях также будет ошибочным (из-за дополнительногоN'Z'
символа в начале).ОДНАКО, это может быть достигнуто с помощью SQLCLR. Довольно просто создать скалярную функцию, которая принимает два входных параметра типа
NVARCHAR(MAX)
.Следующий пример иллюстрирует эту возможность с помощью бесплатной версии библиотеки SQL # SQLCLR (которую я создал, но String_Contains снова доступен в бесплатной версии :-).
String_Contains скалярных UDF в настоящее время имеют
@SearchValue
вход параметры , какNVARCHAR(4000)
вместо того , чтобыNVARCHAR(MAX)
(я не должен подумать , люди будут искать для строк более 4000 символов ;-) но это очень легко изменить, сделав следующее изменение одноразового (после SQL # было установлено, конечно):НАСТРОИТЬ
ИСПЫТАНИЯ
Помните, что String_Contains использует сравнение с учетом всего (регистр, акцент, кана и ширина).
источник
Поскольку вы также просили альтернативные подходы, другой способ найти конкретный план - это найти его
plan_hash
, изменив ваш запрос следующим образом:Самый быстрый способ найти искомое
QueryHash
значение - это вставить нужный запрос в окно запроса, а затем отобразить примерный план выполнения. Прочитайте вывод XML и найдитеQueryHash
атрибут вStmtSimple
элементе, и это должно дать вам то, что вам нужно. Вставьте значение QueryHash в запрос выше, и, надеюсь, у вас будет то, что вы ищете.Вот несколько скриншотов, показывающих, как быстро получить
QueryHash
значение в случае, если я плохо его объясняю.Просмотр предполагаемого плана выполнения
Показать план выполнения XM ...
Поиск значения QueryHash
Очевидно, что хитрость не сработает, если запрос, который вы ищете, отличается от запроса, для которого вы отображаете Предполагаемый план выполнения, но это может быть быстрее, чем все нюансы, которые идут с подпрограммами CLR и заставляют их работать должным образом.
источник
Если у вас есть доступ к текстам запроса (то есть вы можете изменить их), вы можете добавить уникальные комментарии к тем, кто вас интересует:
затем ищите
myUniqueQuery123
в кэше планов вместо всего текста запроса:PS. Не проверено
источник