Saya memiliki tabel uji berikut di SQL Server 2005:
CREATE TABLE [dbo].[TestTable]
(
[ID] [int] NOT NULL,
[TestField] [varchar](100) NOT NULL
)
Diisi dengan:
INSERT INTO TestTable (ID, TestField) VALUES (1, 'A value'); -- Len = 7
INSERT INTO TestTable (ID, TestField) VALUES (2, 'Another value '); -- Len = 13 + 6 spaces
Ketika saya mencoba menemukan panjang TestField dengan fungsi SQL Server LEN (), itu tidak menghitung spasi tambahan - misalnya:
-- Note: Also results the grid view of TestField do not show trailing spaces (SQL Server 2005).
SELECT
ID,
TestField,
LEN(TestField) As LenOfTestField, -- Does not include trailing spaces
FROM
TestTable
Bagaimana cara menyertakan spasi tambahan dalam hasil panjang?
sql-server
Jason Snelders
sumber
sumber
Jawaban:
Ini dengan jelas didokumentasikan oleh Microsoft di MSDN di http://msdn.microsoft.com/en-us/library/ms190329(SQL.90).aspx , yang menyatakan LEN "mengembalikan jumlah karakter dari ekspresi string yang ditentukan, tidak termasuk membuntuti kosong ". Namun demikian, detail yang mudah dilewatkan jika Anda tidak waspada.
Anda harus menggunakan fungsi DATALENGTH - lihat http://msdn.microsoft.com/en-us/library/ms173486(SQL.90).aspx - yang "mengembalikan jumlah byte yang digunakan untuk mewakili ekspresi apa pun".
Contoh:
sumber
DATALENGTH
Anda juga perlu membagi hasil dengan 2 jika ekspresi yang diuji adalah tipe karakter lebar (Unicode; nchar, nvarchar atau ntext), karena hasilnya dalam byte , bukan karakter .varchar
dll. Ini dapat bergantung pada pemeriksaan dan bahkan pembagian lurus ke depan dengan 2 tidak dapat diandalkan. Lihat contoh di siniLEN(REPLACE(expr, ' ', '_'))
. Ini harus bekerja denganvarchar
dannvarchar
dan string yang berisi karakter kontrol unicode khusus.DATALENGTH()
tidak boleh dianggap sebagai cara alternatif untuk menghitung karakter karena ini menghitung byte, bukan karakter, dan ini penting saat mewakili string yang sama diVARCHAR
/NVARCHAR
.Anda bisa menggunakan trik ini:
LEN (Str + 'x') - 1
sumber
Saya menggunakan metode ini:
Saya lebih suka ini daripada DATALENGTH karena ini berfungsi dengan tipe data yang berbeda, dan saya lebih suka menambahkan karakter di akhir karena Anda tidak perlu khawatir tentang kasus tepi di mana string Anda sudah berada pada panjang maksimal.
Catatan: Saya akan menguji performanya sebelum menggunakannya terhadap kumpulan data yang sangat besar; meskipun saya baru saja mengujinya terhadap 2 juta baris dan itu tidak lebih lambat dari LEN tanpa REPLACE ...
sumber
Anda meminta seseorang untuk mengajukan permintaan peningkatan SQL Server / laporan bug karena hampir semua solusi yang terdaftar untuk masalah yang sangat sederhana ini memiliki beberapa kekurangan atau tidak efisien. Ini tampaknya masih berlaku di SQL Server 2012. Fitur pemangkasan otomatis mungkin berasal dari ANSI / ISO SQL-92 tetapi tampaknya ada beberapa lubang (atau kurangnya menghitungnya).
Harap beri suara "Tambahkan setelan sehingga LEN menghitung spasi kosong" di sini:
https://feedback.azure.com/forums/908035-sql-server/suggestions/34673914-add-setting-so-len-counts-trailing-whitespace
Tautan koneksi yang dihentikan: https://connect.microsoft.com/SQLServer/feedback/details/801381
sumber
datalength
solusi bahkan lebih buruk mulai dari SQL Server 2012, karena itu sekarang mendukung pasangan pengganti di UTF-16, yang berarti karakter dapat menggunakan hingga 4 bytes. Sudah saatnya mereka memperbaikilen
fungsi agar sesuai dengan ANSI, atau setidaknya menyediakan fungsi khusus untuk menghitung karakter termasuk spasi tambahan.Ada masalah dengan dua jawaban pilihan teratas. Jawaban yang direkomendasikan
DATALENGTH
rentan terhadap kesalahan programmer. Hasil dariDATALENGTH
harus dibagi 2 untukNVARCHAR
tipe, tetapi tidak untukVARCHAR
tipe. Ini membutuhkan pengetahuan tentang jenis yang Anda dapatkan panjangnya, dan jika jenis itu berubah, Anda harus rajin mengubah tempat yang Anda gunakanDATALENGTH
.Ada juga masalah dengan jawaban yang paling banyak dipilih (yang saya akui adalah cara yang saya pilih untuk melakukannya sampai masalah ini menggigit saya). Jika hal yang Anda dapatkan panjangnya adalah tipe
NVARCHAR(4000)
, dan itu benar-benar berisi string 4000 karakter, SQL akan mengabaikan karakter yang ditambahkan daripada secara implisit menampilkan hasilnyaNVARCHAR(MAX)
. Hasil akhirnya adalah panjang yang salah. Hal yang sama akan terjadi dengan VARCHAR (8000).Apa yang saya temukan berfungsi, hampir secepat lama biasa
LEN
, lebih cepat daripadaLEN(@s + 'x') - 1
string besar, dan tidak mengasumsikan lebar karakter yang mendasarinya adalah sebagai berikut:Ini mendapatkan datalength, dan kemudian membaginya dengan datalength karakter tunggal dari string. Penambahan 'x' mencakup kasus di mana string kosong (yang akan memberikan pembagian dengan nol dalam kasus itu). Ini berfungsi baik
@s
ituVARCHAR
atauNVARCHAR
. MelakukanLEFT
of 1 karakter sebelum append memotong beberapa waktu ketika stringnya besar. Masalahnya dengan ini, adalah bahwa itu tidak bekerja dengan benar dengan string yang mengandung pasangan pengganti.Ada cara lain yang disebutkan dalam komentar untuk jawaban yang diterima, menggunakan
REPLACE(@s,' ','x')
. Teknik itu memberikan jawaban yang benar, tetapi beberapa kali lipat lebih lambat daripada teknik lain ketika stringnya besar.Mengingat masalah yang diperkenalkan oleh pasangan pengganti pada teknik apa pun yang digunakan
DATALENGTH
, menurut saya metode teraman yang memberikan jawaban benar yang saya ketahui adalah sebagai berikut:Ini lebih cepat daripada
REPLACE
tekniknya, dan jauh lebih cepat dengan senar yang lebih panjang. Pada dasarnya teknik ini adalahLEN(@s + 'x') - 1
teknik, tetapi dengan perlindungan untuk kasus tepi di mana string memiliki panjang 4000 (untuk nvarchar) atau 8000 (untuk varchar), sehingga jawaban yang benar diberikan bahkan untuk itu. Ini juga harus menangani string dengan pasangan pengganti dengan benar.sumber
N'x𤭢x' COLLATE Latin1_General_100_CI_AS_SC
memberikan 4, sementaraLEN
memberikan 3.Anda juga perlu memastikan bahwa data Anda benar-benar disimpan dengan trailing blank. Saat ANSI PADDING MATI (non-default):
sumber
LEN memotong spasi di belakang secara default, jadi menurut saya ini berfungsi saat Anda memindahkannya ke depan
(LEN (MUNDUR (TestField))
Jadi kalau mau, bisa dibilang
Jangan gunakan ini untuk spasi utama tentunya.
sumber
declare @TestField varchar(10);
SET @TestField = ' abc '; -- Length with spaces is 5.
select LEN(REVERSE(@TestField)) -- Returns 4
select LEN(@TestField) -- Returns 4
Anda harus menentukan fungsi CLR yang mengembalikan bidang Panjang String, jika Anda tidak menyukai penggabungan string. Saya gunakan
LEN('x' + @string + 'x') - 2
dalam kasus penggunaan produksi saya.sumber
Jika Anda tidak menyukai
DATALENGTH
karena kekhawatiran n / varchar, bagaimana dengan:yang adil
dibungkus dengan perlindungan bagi-dengan-nol.
Dengan membaginya dengan DATALENGTH karakter tunggal, kita mendapatkan panjangnya dinormalisasi.
(Tentu saja, masih masalah dengan pasangan pengganti jika itu menjadi perhatian.)
sumber
gunakan SELECT DATALENGTH ('string')
sumber