2011-12-09 146 views
5

我想从表Users表中选择行,其中列Logon等于"foo" - 但是,我也想要返回"Foo""FOO"在Oracle中有没有办法让列不区分大小写?

我可以这样做:

SELECT Id, Name FROM Users WHERE UPPER(Logon) = 'FOO'; 

然后我的参数转换为大写。然而,在我们的代码中,我们有几百个地方需要更新。

有没有办法让表模式本身不区分大小写,所以这些查询将不加修改地工作?谢谢!

UPDATE

我不想在整个数据库或会话级的更改大小写。更改SQL查询很困难,因为我们使用.NET实体框架,并且对这个表进行LINQ查询。它不会出现EF支持自动转换的情况下,除非你想改变每一个LINQ查询。

+0

检查http://stackoverflow.com/questions/2001165/oracle-11g-case-insensi tive-by-default – a1ex07

+0

我正在寻找一种具有表和/或列级别控制的方法,我现在不想更改整个数据库。 –

回答

3

回答我自己的问题,因为我不觉得任何一个建议的答案真的解决了这个问题。

Oracle不支持不区分大小写的列类型的概念,区分大小写只能在数据库或会话级别进行控制。有几种方法可以解决这个问题,比如让虚拟列变成虚拟的或者通过视图来读取,但是它们中的每一个都会要求你施放右边的操作数(比如WHERE X = UPPER(:p1)

我最终更新了数据库(这是来自Active Directory的用户名列表),以便拥有正确的病例,因此我不再需要比较不区分大小写。

0

可以建立一个视图上的表具有相同的所有列,除了这将挂高档受影响的列 - 是这样的:

create view v_Users as 
select Id, Name, UPPER(Logon) Logon, ... 
FROM Users 

- 然后做一个全球性的源代码替换将表格名称更改为视图名称 - 虽然如果您的表格被称为用户,这可能是相当危险的...

+2

他也必须改变他的所有查询以将登录传递为大写,这正是他试图避免的。 –

+1

是的,这是一个想法,但我仍然必须重新编写所有的选择,以将右操作数转换为大写。如果我要这样做,我不妨更新我通过登录查找用户的所有地方 - 我认为这是我必须做的:) –

1

我不认为你可以只为一列。您可以尝试以下方法:使您的Logon列虚拟为UPPER(s_Logon)(创建s_Logon,复制现有Logon列中的所有值,并删除Logon,将其创建为虚拟)。我相信它会适用于SELECT s,但对于insert/update s,您将需要访问's_Logon'。希望这是有道理的。

+0

难道这不会让列始终处于大写状态?当我比较它时,我仍然必须将右操作数转换为大写。 –

2

我宁愿不改变整个数据库或会话中的区分大小写级别

是否有办法让表模式本身不区分大小写,这样这些查询就可以不加修改地工作

是的,这是可能的,但从版本Oracle 12cR2及以上。你可以把它定义在许多层面上(列,表,架构):

-- default 
CREATE TABLE tab2(i INT PRIMARY KEY, name VARCHAR2(100)); 

INSERT INTO tab2(i, name) VALUES (1, 'John'); 
INSERT INTO tab2(i, name) VALUES (2, 'Joe'); 
INSERT INTO tab2(i, name) VALUES (3, 'Billy'); 

SELECT /*csv*/ * 
FROM tab2 
WHERE name = 'jOHN' ; 
/* 
"I","NAME" 
no rows selected 
*/ 

SELECT /*csv*/ 
     column_id, 
     column_name, 
     collation 
FROM user_tab_columns 
WHERE table_name = 'TAB2' 
ORDER BY column_id; 
/* 
"COLUMN_ID","COLUMN_NAME","COLLATION" 
1,"I","" 
2,"NAME","USING_NLS_COMP" 
*/ 

列级:

CREATE TABLE tab2(i INT PRIMARY KEY, name VARCHAR2(100) COLLATE BINARY_CI); 

INSERT INTO tab2(i, name) VALUES (1, 'John'); 
INSERT INTO tab2(i, name) VALUES (2, 'Joe'); 
INSERT INTO tab2(i, name) VALUES (3, 'Billy'); 

SELECT /*csv*/ * 
FROM tab2 
WHERE name = 'jOHN' ; 
/* 
"I","NAME" 
1,"John" 
*/ 

-- COLUMN LEVEL 

SELECT /*csv*/ 
     column_id, 
     column_name, 
     collation 
FROM user_tab_columns 
WHERE table_name = 'TAB2' 
ORDER BY column_id; 
/* 
"COLUMN_ID","COLUMN_NAME","COLLATION" 
1,"I","" 
2,"NAME","BINARY_CI" 
*/ 

表级:

CREATE TABLE tab2(i INT PRIMARY KEY, name VARCHAR2(100)) 
DEFAULT COLLATION BINARY_CI; 

模式级:

CREATE USER myuser IDENTIFIED BY myuser 
DEFAULT TABLESPACE users 
DEFAULT COLLATION BINARY_CI; 
+1

整洁的功能 - 没有听说过这个。更多信息:https://oracle-base.com/articles/12c/column-level-collat​​ion-and-case-insensitive-database-12cr2 –

相关问题