我想通過字符串匹配從sqlite3數據庫中選擇記錄。但是如果我在where子句中使用'=',我發現sqlite3區分大小寫。任何人都可以告訴我如何使用字符串比較不區分大小寫?如何設置Sqlite3在字符串比較時不區分大小寫?
回答
您可以在SELECT
查詢中使用COLLATE NOCASE
:。
SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE
另外,在SQLite中,通過在列定義中指定collate nocase
(其他選項爲binary
(默認值)和rtrim
)創建表時,您可以指示列應該不區分大小寫;見here)。您也可以在創建索引時指定collate nocase
。例如:
create table Test ( Text_Value text collate nocase ); insert into Test values ('A'); insert into Test values ('b'); insert into Test values ('C'); create index Test_Text_Value_Index on Test (Text_Value collate nocase);
涉及Test.Text_Value
的表達式現在應該不區分大小寫。例如:
sqlite> select Text_Value from Test where Text_Value = 'B'; Text_Value ---------------- b sqlite> select Text_Value from Test order by Text_Value; Text_Value ---------------- A b C sqlite> select Text_Value from Test order by Text_Value desc; Text_Value ---------------- C b A
優化程序還可能使用索引進行不區分大小寫的搜索和匹配列。您可以在此使用explain
SQL命令,例如:
sqlite> explain select Text_Value from Test where Text_Value = 'b'; addr opcode p1 p2 p3 ---------------- -------------- ---------- ---------- --------------------------------- 0 Goto 0 16 1 Integer 0 0 2 OpenRead 1 3 keyinfo(1,NOCASE) 3 SetNumColumns 1 2 4 String8 0 0 b 5 IsNull -1 14 6 MakeRecord 1 0 a 7 MemStore 0 0 8 MoveGe 1 14 9 MemLoad 0 0 10 IdxGE 1 14 + 11 Column 1 0 12 Callback 1 0 13 Next 1 9 14 Close 1 0 15 Halt 0 0 16 Transaction 0 0 17 VerifyCookie 0 4 18 Goto 0 1 19 Noop 0 0
這不是具體到sqlite的,但你可以做
SELECT * FROM ... WHERE UPPER(name) = UPPER('someone')
你可以這樣說:
SELECT * FROM ... WHERE name LIKE 'someone'
(這不是的解決方案,但在某些情況下是非常方便)
「The LIKE歌劇tor做了一個匹配比較的模式 。 右側的操作數包含模式,左側操作數包含字符串 以匹配模式。模式 中的 百分號(「%」)與字符串中的零個或多個 字符的任何序列匹配。模式 中的 下劃線(「_」)與 字符串中的任何單個字符匹配。 任何其他字符匹配 本身或它的下/上殼體 等效(即,不區分大小寫 匹配)。 (A錯誤:SQLite的僅 理解爲ASCII 字符/小寫LIKE運算符是區分 爲Unicode字符 超出ASCII範圍敏感對於 例如,表達式「a」 LIKE「A」 是。真實的,但 'æ' LIKE 'Æ' 爲FALSE)「
SELECT * FROM ... WHERE name = 'someone' COLLATE NOCASE
如果列char
類型的檢查,那麼你需要添加你用空格查詢值,請參考這個問題here。這除了使用COLLATE NOCASE
或其他解決方案之一(upper()等)之外。
另一種選擇是創建自己的自定義排序規則。然後,您可以在該列上設置該排序規則,或將其添加到您的select子句中。它將用於排序和比較。
這可以用來使'VOILA'像'voilà'。
http://www.sqlite.org/capi3ref.html#sqlite3_create_collation
覈對功能必須返回一個整數,它是負,零,或者如果第一串分別比第二小於,等於,或大於,陽性。
您的情況可能有意義也可能沒有意義的另一個選擇是實際上有一個單獨的列,其中包含您的現有列的低前值。這可以使用SQLite函數LOWER()
進行填充,然後您可以對該列執行匹配。
顯然,它增加了冗餘性和潛在的不一致性,但是如果你的數據是靜態的,它可能是一個合適的選擇。
您可以使用類似查詢來將各個字符串與表值進行比較。
從table_name中選擇列名稱,其中列名稱爲'各自的比較值';
它爲我工作完美。 SELECT NAME FROM TABLE_NAME WHERE NAME = 'test Name' COLLATE NOCASE
這樣做是否會損失性能? – quantity 2009-06-10 03:40:49
性能問題的另一部分是在表中查找匹配的行。 SQLite3是否支持基於函數的索引?在這種情況下對搜索列或表達式進行索引(例如「UPPER(name)」)通常是一個好主意。 – cheduardo 2009-06-10 04:03:25
小心這個,正如cheduardo暗示的那樣,SQLite在運行此查詢時無法使用'name'上的索引。數據庫引擎將需要全面掃描所有行,將所有'名稱'字段轉換爲大寫並運行比較。 – 2012-03-15 08:58:58