2010-10-11 59 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