Oracle中是否有办法使列不区分大小写?

时间:2011-12-09 17:17:37

标签: sql oracle entity-framework oracle11g case-insensitive

我想从名为Users的表中选择行Logon等于"foo"的行 - 但是,我还想返回"Foo"或{{1 }}

我可以这样做:

"FOO"

然后将我的参数转换为大写。但是,在我们的代码中,我们有数百个点,我们必须更新它。

有没有办法让表模式本身不区分大小写,所以这些查询只能在不修改的情况下工作?谢谢!

更新

我宁愿不在整个数据库或会话级别更改区分大小写。更改SQL查询很难,因为我们使用.NET实体框架并且在整个地方都对这个表进行LINQ查询。除非您想要更改每个LINQ查询,否则EF似乎不支持自动转换大小写。

4 个答案:

答案 0 :(得分:3)

回答我自己的问题,因为我觉得任何一个提议的答案都没有真正解决这个问题。

Oracle不支持不区分大小写的列类型的概念,并且只能在数据库或会话级别控制区分大小写。有几种方法可以解决这个问题,例如将列设置为虚拟或通过视图进行读取,但是每个方法也需要您投射正确的操作数(例如WHERE X = UPPER(:p1)

我最后只更新了我的数据库(这是Active Directory中的用户名列表)以获得正确的案例,因此我不再需要比较不区分大小写。

答案 1 :(得分:3)

  

我宁愿不在整个数据库或会话级别更改区分大小写。

     

有没有办法让表架构本身不区分大小写,因此这些查询只会在不修改的情况下工作

是的,可以从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;

答案 2 :(得分:1)

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

答案 3 :(得分:0)

可以在您的桌面上设置一个视图,所有列都相同,但受影响的列将被升级 - 例如:

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

- 然后对源代码进行全局替换,将表名更改为视图名称 - 尽管如果您的表名为Users,那可能非常危险......