Изразите се преобразуват в настройки на NLS сесия в DML, но не и в DDL.
Това вероятно е грешка с поведението на NLSSORT(char, 'NLS_SORT=BINARY')
.
От ръководството :"Ако посочите BINARY, тогава тази функция връща char." Но това не е вярно за индекса. Обикновено е много удобно изразът на индекса да не претърпява никаква трансформация; ако зависеше от настройките на сесията, инструменти като DBMS_METADATA.GET_DDL ще трябва да върнат много alter session
изявления. Но в този случай това означава, че можете да създадете индекс, който никога няма да бъде използван.
Планът за обяснение показва истинското изразяване. Ето как Oracle използва nlssort
в сесия, без да се използва изрично:
alter session set nls_comp=linguistic;
alter session set nls_sort=binary_ai;
drop table raw_screen;
create table raw_screen (
id number(10) constraint rscr_pk primary key,
name nvarchar2(256) not null
);
create unique index idx_binary_ai
on raw_screen (nlssort(name, 'nls_sort=binary_ai'));
explain plan for select * from raw_screen where name = n'raw_screen1000';
select * from table(dbms_xplan.display(format=>'basic predicate'));
Plan hash value: 2639454581
-----------------------------------------------------
| Id | Operation | Name |
-----------------------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | TABLE ACCESS BY INDEX ROWID| RAW_SCREEN |
|* 2 | INDEX UNIQUE SCAN | IDX_BINARY_AI |
-----------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access(NLSSORT("NAME",'nls_sort=''BINARY_AI''')=HEXTORAW('0072006
10077005F00730063007200650065006E003100300030003000'))
Този пример показва, че nlssort(char, 'nls_sort=binary')
се изпуска от DML:
alter session set nls_comp=linguistic;
alter session set nls_sort=binary_ai;
drop table raw_screen;
create table raw_screen (
id number(10) constraint rscr_pk primary key,
name nvarchar2(256) not null
);
create unique index idx_binary_ai on
raw_screen (nlssort(name, 'nls_sort=binary_ai'));
explain plan for select * from raw_screen where
nlssort(name,'nls_sort=binary') = nlssort(N'raw_screen1000','nls_sort=binary');
select * from table(dbms_xplan.display(format=>'basic predicate'));
Plan hash value: 237065300
----------------------------------------
| Id | Operation | Name |
----------------------------------------
| 0 | SELECT STATEMENT | |
|* 1 | TABLE ACCESS FULL| RAW_SCREEN |
----------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("NAME"=U'raw_screen1000')
В обобщение - индексът DDL трябва да съвпада точно с трансформирания изрази, които могат да зависят от настройките на сесията и необичайното поведение на binary
.