Yana saf T-SQL çözülebileceğini görünen ne değildir CHARINDEX
, ne de PATINDEX
dize "aramak için" (8000 yani max fazla 8000 bayt kullanarak izin VARCHAR
veya 4000 NVARCHAR
karakterden). Bu aşağıdaki testlerde görülebilir:
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
Bu sorguların her ikisi de aşağıdaki hatayı döndürür:
Msg 8152, Seviye 16, Durum 10, Satır xxxxx
Dize veya ikili veriler kesilir.
Ve 7000
bu sorgulardan herhangi birinde azaltmak 3999
hatadan kurtulmak için. Her 4000
iki durumda da bir değer hata verir ( N'Z'
başlangıçtaki ekstra karakterden dolayı ).
Ancak, bu SQLCLR kullanılarak gerçekleştirilebilir. İki tür giriş parametresini kabul eden bir skaler fonksiyon oluşturmak oldukça basittir NVARCHAR(MAX)
.
Aşağıdaki örnek, SQL # SQLCLR kütüphanesinin Ücretsiz sürümünü (oluşturduğum ancak String_Contains'ı yine Ücretsiz sürümü :-) kullanılabilir kullanarak bu yeteneği göstermektedir .
KURMAK
-- 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;
TESTLERİ
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
Lütfen String_Contains'ın her şeye duyarlı (büyük / küçük harf, aksan, Kana ve genişlik) karşılaştırmayı kullandığını unutmayın.
where st.text like '%MY_QUERY%CHARS%' ESCAPE '?'