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) 42ilki için kullanmak REPLICATE, böylece grup başına 43 değişken kullanmak ve sonra 762ikincisi 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 @Sdeğ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( Int16başlayan IF .NET içinde) 0(max değeri 32.767 olan ancak birçok / en programlama dillerinde diziler 0 tabanlıdır).