Есть ли способ в Oracle, чтобы сделать столбец без учета регистра? - PullRequest
5 голосов
/ 09 декабря 2011

Я хочу выбрать строки из таблицы с именем Users, где столбец Logon равен "foo" - Однако я также хочу вернуть "Foo" или "FOO".

Iможет сделать что-то вроде:

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

И затем преобразовать мой параметр в верхний регистр.Тем не менее, в нашем коде есть буквально сотни мест, где мы должны были бы обновить это.

Есть ли способ сделать саму схему таблицы нечувствительной к регистру, чтобы эти запросы просто работали без изменений?Спасибо!

ОБНОВЛЕНИЕ

Я бы не стал менять чувствительность к регистру во всей базе данных или на уровне сеанса.Изменить запросы SQL сложно, так как мы используем .NET Entity Framework и везде используем запросы LINQ к этой таблице.Похоже, EF не поддерживает автоматическое преобразование регистра, если вы не хотите изменять также каждый запрос LINQ.

Ответы [ 4 ]

3 голосов
/ 15 февраля 2018

Я бы не хотел менять чувствительность к регистру во всей базе данных или на уровне сеанса.

Есть ли способ сделать саму схему таблицы без учета регистра, чтобы эти запросы просто работали без изменений

Да, это возможно, но с версии 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;
3 голосов
/ 23 января 2012

Отвечая на мой собственный вопрос, потому что я не чувствовал, что любой из предложенных ответов действительно решает проблему.

Oracle не поддерживает концепцию нечувствительного к регистру типа столбца, а чувствительность к регистру можно контролировать только на уровне базы данных или сеанса. Есть несколько способов обойти это, например, сделать столбец виртуальным или прочитать представление, но каждый из них также потребует, чтобы вы также приводили правильный операнд (например, WHERE X = UPPER(:p1).

В итоге я просто обновил свою базу данных (которая представляла собой список имен пользователей из Active Directory), чтобы получить правильные регистры, поэтому мне больше не нужно сравнивать регистр без учета регистра.

1 голос
/ 09 декабря 2011

Я не думаю, что вы можете сделать это только для одного столбца. Вы можете попробовать следующий подход: сделать виртуальный столбец Logon как UPPER(s_Logon) (создать s_Logon, скопировать все значения из существующего столбца Logon, удалить Logon, создать его как виртуальный). Я полагаю, что это сработает в течение SELECT с, но для insert/update с вам потребуется доступ к s_Logon. Надеюсь, что это имеет смысл.

0 голосов
/ 09 декабря 2011

Вы могли бы настроить представление на своей таблице со всеми идентичными столбцами, за исключением затронутого столбца, который будет смещен вверх - что-то вроде:

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

- затем выполните глобальноезамените исходный код, чтобы заменить имя таблицы на имя представления - хотя, если ваша таблица называется «Пользователи», это может быть довольно опасно ...

...