이 이후 순수 T-SQL에서 해결 될 수있는 표시도하지 CHARINDEX
않고 PATINDEX
문자열 "검색하기"(8000, 즉 최대에 8000 개 이상의 바이트를 사용하여 허용 VARCHAR
또는 4000 NVARCHAR
자). 이것은 다음 테스트에서 볼 수 있습니다.
SELECT 1 WHERE CHARINDEX(N'Z' + REPLICATE(CONVERT(NVARCHAR(MAX), N'a'), 7000),
N'Z' + REPLICATE(CONVERT(NVARCHAR(MAX), N'a'), 6000)) > 0
SELECT 1 WHERE PATINDEX(N'Z' + REPLICATE(CONVERT(NVARCHAR(MAX), N'a'), 7000),
N'Z' + REPLICATE(CONVERT(NVARCHAR(MAX), N'a'), 6000)) > 0
두 쿼리 모두 다음 오류를 반환합니다.
메시지 8152, 수준 16, 상태 10, 줄 xxxxx
문자열 또는 이진 데이터가 잘립니다.
그리고 7000
이러한 쿼리 중 하나를 줄이면 3999
오류가 제거됩니다. 4000
두 경우 모두 의 값은 N'Z'
시작 부분 의 추가 문자 로 인해 오류도 발생 합니다.
그러나 이는 SQLCLR을 사용하여 수행 할 수 있습니다. 유형의 두 개의 입력 매개 변수를 허용하는 스칼라 함수를 작성하는 것은 매우 간단합니다 NVARCHAR(MAX)
.
다음 예제는 SQL # SQLCLR 라이브러리 의 무료 버전을 사용하여이 기능을 보여줍니다 (제작했지만 String_Contains 는 무료 버전에서 다시 사용할 수 있습니다 :-).
설정
-- DROP TABLE #ContainsData;
CREATE TABLE #ContainsData
(
ContainsDataID INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
Col1 NVARCHAR(MAX) NOT NULL
);
INSERT INTO #ContainsData ([Col1])
VALUES (N'Q' + REPLICATE(CONVERT(NVARCHAR(MAX), N'a'), 15000)),
(N'W' + REPLICATE(CONVERT(NVARCHAR(MAX), N'a'), 20000)),
(N'Z' + REPLICATE(CONVERT(NVARCHAR(MAX), N'a'), 70000));
-- verify the lengths being over 8000
SELECT tmp.[ContainsDataID], tmp.[Col1], DATALENGTH(tmp.[Col1])
FROM #ContainsData tmp;
테스트
SELECT tmp.[ContainsDataID], tmp.[Col1], DATALENGTH(tmp.[Col1])
FROM #ContainsData tmp
WHERE SQL#.String_Contains(tmp.[Col1], REPLICATE(CONVERT(NVARCHAR(MAX), N'a'), 15100)) = 1;
-- IDs returned: 2 and 3
SELECT tmp.[ContainsDataID], tmp.[Col1], DATALENGTH(tmp.[Col1])
FROM #ContainsData tmp
WHERE SQL#.String_Contains(tmp.[Col1], REPLICATE(CONVERT(NVARCHAR(MAX), N'a'), 26100)) = 1;
-- IDs returned: 3
것을 명심하시기 바랍니다 String_Contains가 모든 민감한 (케이스, 악센트, 가나 및 폭) 비교를 사용하고 있습니다.
where st.text like '%MY_QUERY%CHARS%' ESCAPE '?'