Oracle sql case sensitive index

1.3k Views Asked by At

In my project database present table Products, one column called 'Name' So, this table can contain 'Product A' and 'Product a' Both products should be selected in simple select query.

I am created index: CREATE INDEX IDX_PRODUCT_NAME ON PRODUCTS(NAME)

And after that ran SQL query: SELECT /*+ INDEX(PRODUCTS IDX_PRODUCT_NAME)*/ * FROM PRODUCTS WHERE NAME='Product_a'

What I did incorrect?

P.S. I know about variant with changing session flags: NLS_COMP=ANSI; NLS_SORT=BINARY_CI; But for me interesting variant without changes to db settings, does it possible? Or e.g. change this flag only for my query.

Please, take a look picture

UPDATE: William Robertson helped me in comments. CREATE INDEX IDX_PRODUCT_NAME ON PRODUCTS(UPPER(NAME))

After that run query: SELECT * FROM PRODUCTS WHERE **UPPER**(NAME)='PRODUCT_A' And this variant works fine!

1

There are 1 best solutions below

2
William Robertson On

One approach would be to add a virtual column:

create table demo_products
( id          integer not null
, name        varchar2(20)
, name_upper  generated always as (upper(name)) );

create index demo_prod_upper_name_ix on demo_products(name_upper);

insert all
    into demo_products (id, name) values (1, 'Prod A')
    into demo_products (id, name) values (2, 'Prod a')
    into demo_products (id, name) values (3, 'Prod B')
    into demo_products (id, name) values (4, 'Prod b')
    into demo_products (id, name) values (5, 'prod A')
    into demo_products (id, name) values (6, 'Cheese')
    into demo_products (id, name) values (7, 'Bananas')
select * from dual;

commit;

select count(*) from demo_products where name_upper = 'PROD A';

  COUNT(*)
----------
         3

Plan hash value: 4158816492

---------------------------------------------------------------------------------------------
| Id  | Operation         | Name                    | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |                         |     1 |    12 |     1   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE   |                         |     1 |    12 |            |          |
|*  2 |   INDEX RANGE SCAN| DEMO_PROD_UPPER_NAME_IX |     1 |    12 |     1   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("NAME_UPPER"='PROD A')