Bagaimana cara membuat kueri SQL (MS SQL Server) di mana klausa "di mana" tidak peka huruf besar / kecil?
SELECT * FROM myTable WHERE myField = 'sOmeVal'
Saya ingin hasilnya kembali dengan mengabaikan kasus ini
Bagaimana cara membuat kueri SQL (MS SQL Server) di mana klausa "di mana" tidak peka huruf besar / kecil?
SELECT * FROM myTable WHERE myField = 'sOmeVal'
Saya ingin hasilnya kembali dengan mengabaikan kasus ini
Jawaban:
Dalam konfigurasi default database SQL Server, perbandingan string adalah case-sensitive. Jika database Anda menimpa pengaturan ini (melalui penggunaan pemeriksaan alternatif), maka Anda harus menentukan jenis pemeriksaan yang akan digunakan dalam kueri Anda.
SELECT * FROM myTable WHERE myField = 'sOmeVal' COLLATE SQL_Latin1_General_CP1_CI_AS
Perhatikan bahwa pemeriksaan yang saya berikan hanyalah sebuah contoh (meskipun kemungkinan besar akan berfungsi dengan baik untuk Anda). Garis besar pemeriksaan SQL Server yang lebih menyeluruh dapat ditemukan di sini .
UPPER
atau LOWER
kapitalisasi lalu menggunakan LIKE
untuk mencari?
Biasanya, perbandingan string tidak peka huruf besar / kecil. Jika database Anda dikonfigurasi untuk pemeriksaan case-sensitive, Anda perlu memaksa untuk menggunakan case tidak sensitif:
SELECT balance FROM people WHERE email = 'billg@microsoft.com'
COLLATE SQL_Latin1_General_CP1_CI_AS
Saya menemukan solusi lain di tempat lain; yaitu, untuk digunakan
upper(@yourString)
tetapi semua orang di sini mengatakan bahwa, di SQL Server, tidak masalah karena tetap mengabaikan kasus? Saya cukup yakin database kita peka huruf besar kecil.
2 jawaban teratas (dari Adam Robinson dan Andrejs Cainikovs ) agak, agak benar, karena secara teknis berhasil, tetapi penjelasan mereka salah dan bisa menyesatkan dalam banyak kasus. Misalnya, meskipun SQL_Latin1_General_CP1_CI_AS
pemeriksaan akan berfungsi dalam banyak kasus, pemeriksaan tersebut tidak boleh dianggap sebagai pemeriksaan tidak peka huruf besar / kecil. Faktanya, mengingat bahwa OP bekerja dalam database dengan pemeriksaan case-sensitive (atau mungkin biner), kita tahu bahwa OP tidak menggunakan pemeriksaan yang merupakan default untuk begitu banyak instalasi (terutama yang diinstal pada OS. menggunakan bahasa Inggris AS sebagai bahasa): SQL_Latin1_General_CP1_CI_AS
. Tentu, OP bisa digunakan SQL_Latin1_General_CP1_CS_AS
, tapi saat bekerja denganVARCHAR
data, penting untuk tidak mengubah halaman kode karena dapat menyebabkan hilangnya data, dan itu dikontrol oleh lokal / budaya pemeriksaan (yaitu Latin1_General vs Perancis vs Ibrani dll). Silakan lihat poin # 9 di bawah.
Empat jawaban lainnya salah dalam berbagai tingkatan.
Saya akan mengklarifikasi semua kesalahpahaman di sini sehingga pembaca dapat membuat pilihan yang paling tepat / efisien.
Jangan gunakan UPPER()
. Itu benar-benar pekerjaan ekstra yang tidak perlu. Gunakan COLLATE
klausa. Perbandingan string perlu dilakukan dalam kedua kasus, tetapi menggunakan UPPER()
juga harus memeriksa, karakter demi karakter, untuk melihat apakah ada pemetaan huruf besar, dan kemudian mengubahnya. Dan Anda perlu melakukan ini di kedua sisi. Menambahkan COLLATE
hanya mengarahkan pemrosesan untuk menghasilkan kunci sortir menggunakan sekumpulan aturan yang berbeda dari yang akan dilakukan secara default. Menggunakan COLLATE
pasti lebih efisien (atau "performant", jika Anda suka kata itu :) daripada menggunakan UPPER()
, sebagaimana dibuktikan dalam skrip pengujian ini (di PasteBin) .
Ada juga masalah yang dicatat oleh @Ceisc pada jawaban @ Danny:
Dalam beberapa kasus bahasa, konversi tidak bolak-balik. yaitu LOWER (x)! = LOWER (UPPER (x)).
Huruf besar Turki "İ" adalah contoh yang umum.
Tidak, pemeriksaan bukanlah pengaturan seluruh database, setidaknya tidak dalam konteks ini. Ada pemeriksaan default tingkat database, dan digunakan sebagai default untuk kolom yang diubah dan yang baru dibuat yang tidak menentukan COLLATE
klausa (yang mungkin berasal dari kesalahpahaman umum ini), tetapi tidak memengaruhi kueri secara langsung kecuali Anda adalah membandingkan literal string dan variabel dengan literal dan variabel string lain, atau Anda mereferensikan meta-data tingkat database.
Tidak, pemeriksaan tidak dilakukan per kueri.
Collations adalah per predikat (yaitu sesuatu operan sesuatu) atau ekspresi, bukan per query. Dan ini berlaku untuk seluruh kueri, bukan hanya WHERE
klausa. Ini mencakup JOIN, GROUP BY, ORDER BY, PARTITION BY, dll.
Tidak, jangan ubah ke VARBINARY
(mis. convert(varbinary, myField) = convert(varbinary, 'sOmeVal')
) Karena alasan berikut:
_BIN2
jika Anda menggunakan SQL Server 2008 atau yang lebih baru, jika tidak, Anda tidak punya pilihan selain menggunakan yang diakhiri dengan _BIN
. Jika datanya NVARCHAR
maka tidak masalah lokal mana yang Anda gunakan karena semuanya sama dalam kasus itu, karenanya Latin1_General_100_BIN2
selalu berfungsi. Jika data VARCHAR
, Anda harus menggunakan lokal yang sama bahwa data saat ini dalam (misalnya Latin1_General
, French
, Japanese_XJIS
, dll) karena lokal menentukan halaman kode yang digunakan, dan mengubah halaman kode dapat mengubah data (yaitu kehilangan data).CONVERT()
itu akan menggunakan 30 nilai default. Bahayanya adalah, jika string bisa lebih dari 30 byte, itu akan terpotong secara diam-diam dan Anda kemungkinan akan mendapatkan hasil yang salah dari predikat ini.Tidak, LIKE
tidak selalu peka huruf besar kecil. Ini menggunakan pemeriksaan kolom yang direferensikan, atau pemeriksaan database jika variabel dibandingkan dengan string literal, atau pemeriksaan ditentukan melalui COLLATE
klausa opsional .
LCASE
bukanlah fungsi SQL Server. Tampaknya itu adalah Oracle atau MySQL. Atau mungkin Visual Basic?
Karena konteks pertanyaannya adalah membandingkan kolom dengan string literal, baik pemeriksaan instance (sering disebut sebagai "server") maupun pemeriksaan database tidak berdampak langsung di sini. Kumpulan disimpan per setiap kolom, dan setiap kolom dapat memiliki pemeriksaan yang berbeda, dan pemeriksaan tersebut tidak perlu sama dengan pemeriksaan default database atau pemeriksaan instance. Tentu, pemeriksaan instance adalah default untuk apa yang akan digunakan database yang baru dibuat sebagai pemeriksaan default jika COLLATE
klausa tidak ditentukan saat membuat database. Dan juga, pemeriksaan default database adalah apa yang akan digunakan kolom yang diubah atau yang baru dibuat jika COLLATE
klausa tidak ditentukan.
Anda harus menggunakan pemeriksaan case-insensitive yang sebaliknya sama dengan pemeriksaan kolom. Gunakan kueri berikut untuk menemukan pemeriksaan kolom (ubah nama tabel dan nama skema):
SELECT col.*
FROM sys.columns col
WHERE col.[object_id] = OBJECT_ID(N'dbo.TableName')
AND col.[collation_name] IS NOT NULL;
Kemudian ubah saja _CS
menjadi _CI
. Jadi, Latin1_General_100_CS_AS
akan menjadi Latin1_General_100_CI_AS
.
Jika kolom menggunakan pemeriksaan biner (diakhiri dengan _BIN
atau _BIN2
), temukan pemeriksaan serupa menggunakan kueri berikut:
SELECT *
FROM sys.fn_helpcollations() col
WHERE col.[name] LIKE N'{CurrentCollationMinus"_BIN"}[_]CI[_]%';
Misalnya, dengan asumsi kolom menggunakan Japanese_XJIS_100_BIN2
, lakukan ini:
SELECT *
FROM sys.fn_helpcollations() col
WHERE col.[name] LIKE N'Japanese_XJIS_100[_]CI[_]%';
Untuk info lebih lanjut tentang collations, encoding, dll, silakan kunjungi: Collations Info
Tidak, hanya menggunakan LIKE
tidak akan berhasil. LIKE
mencari nilai yang sama persis dengan pola yang Anda berikan. Dalam hal ini LIKE
hanya akan menemukan teks 'sOmeVal' dan bukan 'someval'.
Solusi praktis menggunakan LCASE()
fungsi tersebut. LCASE('sOmeVal')
mendapatkan string huruf kecil dari teks Anda: 'someval'. Jika Anda menggunakan fungsi ini untuk kedua sisi perbandingan Anda, ini berfungsi:
SELECT * FROM myTable WHERE LCASE(myField) LIKE LCASE('sOmeVal')
Pernyataan tersebut membandingkan dua string huruf kecil, sehingga 'sOmeVal' Anda akan cocok dengan setiap notasi lain dari 'someval' (mis. 'Someval', 'sOMEVAl' dll.).
LCASE()
di SQL Server (setidaknya saya tidak bisa melihat). Saya pikir jawaban ini untuk RDBMS yang sama sekali berbeda. Silakan lihat jawaban saya untuk klarifikasi tentang perbandingan string.
Anda dapat memaksa case sensitive, mentransmisikan ke varbinary seperti itu:
SELECT * FROM myTable
WHERE convert(varbinary, myField) = convert(varbinary, 'sOmeVal')
Anda berada di database apa? Dengan MS SQL Server, ini adalah pengaturan seluruh database, atau Anda dapat menggantinya dengan kata kunci COLLATE.
WHERE
pernyataan, dan akan memengaruhi semuaWHERE
klausa, bukan?