Semua, saya memiliki kueri SQL dinamis yang besar (tidak dapat dihindari). Karena jumlah bidang dalam kriteria pemilihan, string yang berisi SQL dinamis bertambah lebih dari 4000 karakter. Sekarang, saya mengerti bahwa ada 4000 max set NVARCHAR(MAX)
, tapi melihat SQL yang dieksekusi di Server Profiler untuk pernyataan itu
DELARE @SQL NVARCHAR(MAX);
SET @SQL = 'SomeMassiveString > 4000 chars...';
EXEC(@SQL);
GO
Tampaknya berfungsi (!?), untuk kueri lain yang juga besar itu memunculkan kesalahan yang terkait dengan batas 4000 ini (!?), itu pada dasarnya memangkas semua SQL setelah batas 4000 ini dan meninggalkan saya dengan kesalahan sintaksis. Meskipun demikian di profiler, ini menunjukkan kueri SQL dinamis ini secara penuh (!?).
Apa sebenarnya yang terjadi di sini dan haruskah saya mengonversi variabel @SQL ini ke VARCHAR dan melanjutkannya?
Terima kasih atas waktunya.
Ps. Akan menyenangkan juga bisa mencetak lebih dari 4000 karakter untuk melihat kueri besar ini. Berikut ini dibatasi hingga 4000
SELECT CONVERT(XML, @SQL);
PRINT(@SQL);
apakah ada cara keren lainnya?
sumber
Jawaban:
Pemahaman Anda salah.
nvarchar(max)
dapat menyimpan hingga (dan terkadang lebih dari itu) 2GB data (1 miliar karakter byte ganda).Dari nchar dan nvarchar di Buku online tata bahasanya adalah
The
|
karakter cara ini alternatif. yaitu Anda menentukan salah satun
atau literalmax
.Jika Anda memilih untuk menentukan spesifik
n
maka ini harus antara 1 dan 4.000 tetapi menggunakanmax
mendefinisikannya sebagai tipe data objek besar (penggantinyantext
tidak digunakan lagi).Faktanya di SQL Server 2008 tampaknya untuk variabel batas 2GB dapat dilampaui tanpa batas waktu tergantung pada ruang yang cukup di
tempdb
( Ditunjukkan di sini )Mengenai bagian lain dari pertanyaan Anda
Pemotongan saat penggabungan bergantung pada tipe data.
varchar(n) + varchar(n)
akan dipotong menjadi 8.000 karakter.nvarchar(n) + nvarchar(n)
akan dipotong menjadi 4.000 karakter.varchar(n) + nvarchar(n)
akan dipotong menjadi 4.000 karakter.nvarchar
memiliki prioritas yang lebih tinggi sehingga hasilnya adalahnvarchar(4,000)
[n]varchar(max)
+[n]varchar(max)
tidak akan dipotong (untuk <2GB).varchar(max)
+varchar(n)
tidak akan dipotong (untuk <2GB) dan hasilnya akan diketik sebagaivarchar(max)
.varchar(max)
+nvarchar(n)
tidak akan dipotong (untuk <2GB) dan hasilnya akan diketik sebagainvarchar(max)
.nvarchar(max)
+varchar(n)
pertama-tama akan mengubahvarchar(n)
input menjadinvarchar(n)
dan kemudian melakukan penggabungan. Jika panjangvarchar(n)
string lebih dari 4.000 karakter maka cast akan menjadinvarchar(4000)
dan pemotongan akan terjadi .Jenis data literal string
Jika menggunakan
N
awalan dan panjang string <= 4.000 karakter maka akan diketiknvarchar(n)
dimanan
panjang stringnya. JadiN'Foo'
akan diperlakukan sebagainvarchar(3)
contoh. Jika string lebih dari 4.000 karakter itu akan diperlakukan sebagainvarchar(max)
Jika Anda tidak menggunakan
N
awalan dan panjang string <= 8.000 karakter maka akan diketikvarchar(n)
dimanan
panjang stringnya. Jika lebih lamavarchar(max)
Untuk kedua hal di atas jika panjang string adalah nol maka
n
diset ke 1.Elemen sintaks yang lebih baru.
1. The
CONCAT
Fungsi tidak membantu di siniDi atas mengembalikan 8000 untuk kedua metode penggabungan.
2. Hati-hati dengan
+=
Kembali
Perhatikan bahwa
@A
mengalami pemotongan.Cara mengatasi masalah yang Anda alami.
Anda mendapatkan pemotongan baik karena Anda menggabungkan dua
max
tipe data non bersama-sama atau karena Anda menggabungkanvarchar(4001 - 8000)
string ke string yangnvarchar
diketik (genapnvarchar(max)
).Untuk menghindari masalah kedua cukup pastikan bahwa semua literal string (atau setidaknya yang memiliki panjang dalam kisaran 4001 - 8000) diawali dengan
N
.Untuk menghindari masalah pertama, ubah tugas dari
Untuk
sehingga sebuah
NVARCHAR(MAX)
terlibat dalam penggabungan dari awal (sebagai hasil dari setiap penggabungan jugaNVARCHAR(MAX)
akan menyebar)Menghindari pemotongan saat melihat
Pastikan Anda memilih mode "hasil ke kisi", lalu Anda dapat menggunakan
Opsi SSMS memungkinkan Anda menyetel panjang tak terbatas untuk
XML
hasil. Theprocessing-instruction
bit menghindari masalah dengan karakter seperti<
muncul sebagai<
.sumber
nvarchar(4000)
sepanjang jalan. Jika literal string kurang dari 4.000 karakter maka itu akan diperlakukan sebagainvarchar(x)
.nvarchar(x)
Menggabungkannya nilai lain akan dipotong alih-alih dialihkan kenvarchar(max)
DECLARE @SQL NVARCHAR(MAX) = ''; SET @SQL = @SQL +
sehinggaNVARCHAR(MAX)
terlibat dalam penggabungan.N
awalan yang akan diperlakukan sebagainvarchar(max)
tanpanya, itu akan diperlakukan sebagaivarchar(n)
kemudian secara implisit dilemparkan kenvarchar(4000)
saat Anda menggabungkan kenvarchar
Oke, jadi jika nanti masalahnya adalah Anda memiliki kueri yang lebih besar dari ukuran yang diizinkan (yang mungkin terjadi jika terus bertambah) Anda harus memecahnya menjadi beberapa bagian dan mengeksekusi nilai string. Jadi, katakanlah Anda memiliki prosedur tersimpan seperti berikut:
sumber
Anda juga harus menggunakan teks nvarchar. itu berarti Anda hanya perlu memiliki "N" sebelum string besar Anda dan hanya itu! tidak ada batasan lagi
sumber
nvarchar(n)
dimana n adalah panjang string. Jadi N'Foo 'akan diperlakukan sebagainvarchar(3)
contoh. Jika string lebih dari 4.000 karakter itu akan diperlakukan sebagainvarchar(max)
. Jika Anda tidak menggunakan awalan N dan panjang string <= 8.000 karakter maka akan diketikvarchar(n)
dimana n adalah panjang string. Jika lebih lamavarchar(max)
. Untuk kedua hal di atas jika panjang string adalah nol maka n diatur ke 1.Jawaban yang diterima membantu saya tetapi saya tersandung saat melakukan rangkaian varchar yang melibatkan pernyataan kasus. Saya tahu pertanyaan OP tidak melibatkan pernyataan kasus tetapi saya pikir ini akan membantu untuk memposting di sini untuk orang lain seperti saya yang berakhir di sini sambil berjuang untuk membangun pernyataan SQL dinamis yang panjang yang melibatkan pernyataan kasus.
Saat menggunakan pernyataan kasus dengan rangkaian string, aturan yang disebutkan dalam jawaban yang diterima berlaku untuk setiap bagian pernyataan kasus secara independen.
sumber
sumber