2010-10-11 130 views
4

我非常難以使我的DB2(AS/400)查詢不區分大小寫。DB2案例敏感性

例如:

SELECT * 
FROM NameTable 
WHERE LastName = 'smith' 

不會返回任何結果,但下面的返回1000的結果:

SELECT * 
FROM NameTable 
WHERE LastName = 'Smith' 

我讀過把SortSequence/SortType到您的連接字符串,但有過沒有運氣......任何人都有這種感覺?

編輯:

這裏的存儲過程:

BEGIN 
DECLARE CR CURSOR FOR 
SELECT T . ID , 
    T . LASTNAME , 
    T . FIRSTNAME , 
    T . MIDDLENAME , 
    T . STREETNAME || ' ' || T . ADDRESS2 || ' ' || T . CITY || ' ' || T . STATE || ' ' || T . ZIPCODE AS ADDRESS , 
    T . GENDER , 
    T . DOB , 
    T . SSN , 
    T . OTHERINFO , 
    T . APPLICATION 
FROM 
    (SELECT R . * , ROW_NUMBER () OVER () AS ROW_NUM 
    FROM CPSAB32.VW_MYVIEW 
    WHERE R . LASTNAME = IFNULL (@LASTNAME , LASTNAME) 
    AND R . FIRSTNAME = IFNULL (@FIRSTNAME , FIRSTNAME) 
    AND R . MIDDLENAME = IFNULL (@MIDDLENAME , MIDDLENAME) 
    AND R . DOB = IFNULL (@DOB , DOB) 
    AND R . STREETNAME = IFNULL (@STREETNAME , STREETNAME) 
    AND R . CITY = IFNULL (@CITY , CITY) 
    AND R . STATE = IFNULL (@STATE , STATE) 
    AND R . ZIPCODE = IFNULL (@ZIPCODE , ZIPCODE) 
    AND R . SSN = IFNULL (@SSN , SSN) 
    FETCH FIRST 500 ROWS ONLY) 
AS T 
WHERE ROW_NUM <= @MAXRECORDS 
OPTIMIZE FOR 500 ROW ; 

OPEN CR ; 
RETURN ; 
+0

,在跳出我的第一件事情是,你在你的FROM子句中所有的值,但你沒有聲明別名[R FROM CPSAB32.VW_MYVIEW – Leslie 2010-10-27 20:04:43

回答

6

爲什麼不能做到這一點:

WHERE lower(LastName) = 'smith' 

如果你擔心性能(即不使用索引的查詢)請記住,DB2具有函數索引,您可以閱讀關於here的信息。所以基本上,您可以在upper(LastName)上創建索引。

編輯 做調試技術,我在評論中討論的那樣,你可以做這樣的事情:

create table log (msg varchar(100, dt date); 

然後在你的SP,您可以將消息記錄到該表用於調試目的:

insert into log (msg, dt) select 'inside the SP', current_date from sysibm.sysdummy1; 

然後在SP運行之後,您可以從此日誌表中選擇以查看發生了什麼。

+0

@dcp我以後使用R作爲一個別名已經嘗試過,但通常會返回此消息ERROR [HY000] [IBM] [iSeries Access ODBC驅動程序] [DB2 UDB] SQL0255 - 函數不支持查詢。 – mint 2010-10-11 17:05:57

+0

@mint - 嗯,更低似乎是一個非常標準的DB2函數,我記得早在20世紀90年代後期就使用它。這是一個參考:http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=/com.ibm.db29.doc.sqlref/db2z_bif_lower.htm如果您的數據庫不支持較低/ upper,它的確應該很老。 – dcp 2010-10-11 17:09:16

+0

@dcp嗯,我可以運行它的正確的SQL罰款。但在我的應用程序中,我調用了一個存儲過程,然後它似乎失敗了......不知道爲什麼! – mint 2010-10-11 17:10:11

0

當我想要區分大小寫的搜索時,我做了類似的事情。我用UPPER(mtfield) = 'SEARCHSTRING'。我知道這是有效的。

3

如果你想不區分大小寫在你的程序中,嘗試在它使用此選項:

SET OPTION SRTSEQ = *LANGIDSHR ; 

您還應該創建一個索引來支持它的性能。當您將*LANGIDSHR作爲連接屬性時創建索引,然後共享權重索引應可用於以後的作業。 (有多種方法可以使適當的設置生效。)

*LANGIDSHR與您的工作的語言ID相關。可能被視爲「等於」的字符集中的字符(例如'A'和'a'或'ü'和'u')應該被賦予相同的權重(共享)並一起選擇。

+0

...愚蠢的問題:我可以在何時何地執行此聲明? – Neepsnikeep 2017-10-25 12:51:08

+0

這是嵌入式SQL,它必須是程序中的第一個SQL語句,它不是可執行語句。如果您不是在RPG或COBOL中編程,請參閱[本答案](https://stackoverflow.com/a/47164079/2296441)以獲取更多詳細信息。 – jmarkmurphy 2017-11-22 15:26:37

-1

請參見:https://stackoverflow.com/a/47181640/5507619

數據庫設置

有一個數據庫配置設置,可以設置爲database creation。不過,它基於unicode。

CREATE DATABASE yourDB USING COLLATE UCA500R1_S1 

默認Unicode歸類算法由UCA500R1關鍵字而沒有任何屬性來實現。由於默認UCA不能同時包含Unicode所支持的每種語言的整理順序,因此可以指定可選屬性來自定義UCA排序。這些屬性由下劃線(_)字符分隔。 UCA500R1關鍵字和任何屬性形成UCA整理名稱。

Strength屬性確定在比較或比較文本字符串時是否考慮了重音或大小寫。在編寫沒有大小寫或重音的系統時,Strength屬性控制着類似的重要功能。 可能的值是:primary(1),secondary(2),tertiary(3),quaternary(4)和identity(I)。忽略:

  • 口音和情況下,使用主強度水平僅
  • 情況下,使用輔助的強度水平
  • 既不口音也不情況下,使用第三強度電平

幾乎所有字符可以通過前三個強度等級進行區分,因此在大多數地區,默認強度屬性設置爲第三級。但是,如果「替代」屬性(如下所述)設置爲移位,則可以使用四次強度級別來破壞空白字符,標點符號和否則將被忽略的符號之間的關係。身份強度等級用於區分相似字符,如數學大膽小A字符(U + 1D41A)和數學意大利小A字符(U + 1D44E)。

設置強度歸因於較高的水平會減慢文本字符串比較,增加排序鍵的長度。 實例:

  • UCA500R1_S1將整理 「角色」= 「角色」= 「角色」
  • UCA500R1_S2將整理 「角色」= 「角色」 < 「角色」
  • UCA500R1_S3將整理 「角色」 < 「角色」 < 「角色」

這爲我工作。正如你所看到的,...... S2也忽略了案例。

使用newer standard version,它應該是這樣的:

CREATE DATABASE yourDB USING COLLATE CLDR181_S1 

Collation keywords
UCA400R1 = Unicode標準4.0 = CLDR版本1.2
UCA500R1 = Unicode標準5.0 = CLDR版本1.5.1
CLDR181 = Unicode標準5.2 = CLDR版本1.8.1

如果您的數據庫已經創建,那麼我這應該是change the setting的一種方式。

CALL SYSPROC.ADMIN_CMD('UPDATE DB CFG USING DB_COLLNAME UCA500R1_S1 '); 

我確實有執行此問題的問題,但我知道它應該工作。

生成的錶行

其他選項是如generating a upper case row

CREATE TABLE t (
    id   INTEGER NOT NULL PRIMARY KEY, 
    str   VARCHAR(500), 
    ucase_str VARCHAR(500) GENERATED ALWAYS AS (UPPER(str)) 
)@ 

INSERT INTO t(id, str) 
VALUES (1, 'Some String')@ 

SELECT * FROM [email protected] 

ID   STR         UCASE_STR 
----------- ------------------------------------ ------------------------------------ 
      1 Some String       SOME STRING 

    1 record(s) selected. 
+0

OP特別指出AS400,只有這個答案的生成錶行部分是適用的。 – jmarkmurphy 2017-11-08 16:15:36

+0

您可以在AS400機器上擁有「CREATE DATABASE」所需的訪問權限。如果您希望所有查詢都不區分大小寫,則需要相應地設置數據庫。在所有的語句中都有生成的大寫或使用UPPER(...)的解決方法。但是,如果您想更改不區分大小寫等行爲,您當然需要擁有管理員對DB2服務器的訪問權限。對不起,期待這一點。 – Neepsnikeep 2017-11-22 14:40:06

+0

自v5r4之前,'CREATE DATABASE'尚未用於'IBM i'。數據庫表通常使用基於系統CCSID的默認CCSID創建。這通常就足夠了。您可以在創建表格時覆蓋該CCSID。 – jmarkmurphy 2017-11-22 15:33:30