Esinlenerek @ Paul 'in yanıt , bazı araştırmalar yapmışlar ve yığın alanı sınırı concatenations sayısı da, bu doğru ise ve bu yığın alanı bellek bir fonksiyonudur ve dolayısıyla aşağıdaki iki nokta da doğru değişir :
- ek birleştirmeleri tek bir ifadeye sıkıştırmanın bir yolu vardır VE
- ilk yığın alanı sınırlamasını aşmak için bu yöntemi kullanarak, gerçek bir mantıksal sınır (değişken gibi görünmüyor) bulunabilir
İlk olarak, Paul'ün test kodunu dizeleri birleştirmek için uyarladım:
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = N'
DECLARE @S VARCHAR(MAX), @A VARCHAR(MAX) = ''a'';
SET @S = @A';
SET @SQL += REPLICATE(CONVERT(NVARCHAR(MAX), N' + @A'), 3312) + N';';
-- SET @S = @A + @A + @A...
SET @SQL += N'SELECT DATALENGTH(@S) AS [Chars In @S];';
EXECUTE (@SQL);
Bu testle, harika olmayan dizüstü bilgisayarımda (sadece 6 GB RAM) çalışırken alabileceğim en yüksek değer:
- SQL Server 2017 Express Edition LocalDB (14.0.3006) kullanılarak 3311 (toplam 3312 karakter döndürür)
- SQL Server 2012 Developer Edition SP4 (KB4018073) kullanılarak 3512 (toplam 3513 karakter döndürür) (11.0.7001)
8631 hatasını almadan önce .
Daha sonra, işlem birden çok grup birleştirmeyi birleştirecek şekilde parantez kullanarak birleştirmeleri gruplandırmayı denedim. Örneğin:
SET @S = (@A + @A + @A + @A) + (@A + @A + @A + @A) + (@A + @A + @A + @A);
Bunu yaparak 3312 ve 3513 değişkenlerinin önceki sınırlarının çok ötesine geçebildim. Güncellenen kod:
DECLARE @SQL VARCHAR(MAX), @Chunk VARCHAR(MAX);
SET @SQL = '
DECLARE @S VARCHAR(MAX), @A VARCHAR(MAX) = ''a'';
SET @S = (@A+@A)';
SET @Chunk = ' + (@A' + REPLICATE(CONVERT(VARCHAR(MAX), '+@A'), 42) + ')';
SET @SQL += REPLICATE(CONVERT(VARCHAR(MAX), @Chunk), 762) + ';';
SET @SQL += 'SELECT DATALENGTH(@S) AS [Chars In @S];';
-- PRINT @SQL; -- for debug
-- SET @S = (@A+@A) + (@A + @A...) + ...
EXECUTE (@SQL);
Maksimum değerler (benim için) 42
ilki için kullanmak REPLICATE
, böylece grup başına 43 değişken kullanmak ve sonra 762
ikincisi için kullanmak REPLICATE
, böylece her biri 43 değişkenli 762 grup kullanmaktır. İlk grup iki değişkenle kodlanmıştır.
Çıktı artık @S
değişkende 32.768 karakter olduğunu gösteriyor . Başlangıç grubunu (@A+@A+@A)
sadece yerine güncellersem (@A+@A)
şu hatayı alıyorum:
Msg 8632, Seviye 17, Durum 2, Satır XXXXX
Dahili hata: Bir ifade hizmetleri sınırına ulaşıldı. Lütfen sorgunuzda potansiyel olarak karmaşık ifadeler bulun ve bunları basitleştirmeye çalışın.
Hata numarasının öncekinden farklı olduğuna dikkat edin. Şimdi: 8632 . VE, SQL Server 2012 örneğimi veya SQL Server 2017 örneğimi kullansam da aynı sınıra sahibim.
- Burada üst limiti muhtemelen tesadüf değil 32.768 - max kapasite arasında SMALLINT
( Int16
başlayan IF .NET içinde) 0
(max değeri 32.767 olan ancak birçok / en programlama dillerinde diziler 0 tabanlıdır).