2014-08-27 2 views
1

간단한 테이블에서 간단한 함수 기반 인덱스를 만들고 싶지만 오류가 발생합니다. 그래서, 우선은 내가Oracle 11gR2 함수 기반 인덱스 오류

CREATE OR REPLACE FUNCTION promo_function(p_promo_category VARCHAR2) 
RETURN VARCHAR2 DETERMINISTIC IS 
BEGIN 
    RETURN UPPER(p_promo_category); 
END promo_function; 

가 그럼 난이 실행됩니다 함수를 만들었지 만

CREATE INDEX promotions_fbi 
      ON SH.PROMOTIONS (promo_function (promo_category)); 

왜 실패? "PROMO_FUNCTION":이 오류는 ORA-00904입니다 잘못된 식별자 그러나 함수는 쿼리에서 잘 작동 :

SELECT * 
    FROM sh.sales s, 
     sh.promotions p, 
     sh.times t 
WHERE s.promo_id = p.promo_id 
    AND s.time_id = t.time_id 
    AND t.time_id BETWEEN DATE '2000-01-01' AND DATE '2000-03-31' 
    AND promo_function(p.promo_category) = 'AD NEWS'; 

많은 감사합니다!

+1

당신은 SH, 스키마와 테이블 참조를 접두사로 한 설명 할 수 있도록 내가 다른 포인트 릴리스 오전 있지만. 누가 색인을 소유하고 있습니까? 누가 그 기능을 소유하고 있습니까? – APC

+0

동일한 사용자 ("current_user"또는 무엇이든 호출)가 색인을 소유하고 있습니다 (특히 소유하고있는 것입니다. 아직 존재하지 않습니다). 함수도 있습니다. 그래서 위의 쿼리를 삽입 한 이유는 "current_user ",하지만 인덱스를 만들 수 없습니다 – Thomas

+0

그럼 왜 테이블 refs에 스키마 접두사를 붙이고 있습니까? 혼란 스러울뿐입니다. 사람들이 당신을 돕기를 원한다면 당신의 상황에 대해 분명히해야합니다. – APC

답변

3

본질적으로 아무 문제가 없다 당신의 코드. 나는이 같은 함수 기반 인덱스를 만들 수 있습니다

SQL> create table promotions (promo_category varchar2(10)) 
    2/

Table created. 

SQL> CREATE OR REPLACE FUNCTION promo_function 
    2  (p_promo_category in VARCHAR2) 
    3  RETURN VARCHAR2 DETERMINISTIC 
    4 IS 
    5 BEGIN 
    6  RETURN UPPER(p_promo_category); 
    7 END promo_function; 
    8/

Function created. 

SQL> CREATE INDEX promotions_fbi 
    2  ON PROMOTIONS (promo_function (promo_category)); 

Index created. 

SQL> 

내 코드와 당신 사이의 유일한 차이가 나는 INDEX를 CREATE 문에서 테이블을 앞에 없다는 것입니다. 모든 것이 동일한 스키마에 있으므로 필요하지 않습니다.

그래서 시나리오를 다시 만들 수 있습니까? 한 가지 방법이 있습니다. 내가 만드는 경우 나는, 그러나 ... 나는 일반 인덱스를 만들 수있는 사용자로서

SQL> drop index promotions_fbi; 

Index dropped. 

SQL> drop function PROMO_FUNCTION; 

Function dropped. 

SQL> grant all on promotions to B; 

Grant succeeded. 

SQL> 

... 다음 TEH 테이블에 다른 용도로 모든 권한을 부여,

SQL> conn b/b 
Connected. 
SQL> select * from apc.promotions; 

no rows selected 

SQL> CREATE INDEX promotions_i 
    2  ON APC.PROMOTIONS (promo_category); 

Index created. 

SQL> 

를 인덱스 및 기능을 드롭 함수를 사용하여 함수 기반 인덱스를 만들 수 없습니다. ...

SQL> conn b/b 
Connected. 

SQL> CREATE INDEX promotions_fbi 
    2  ON APC.PROMOTIONS (promo_function (promo_category)); 
     ON APC.PROMOTIONS (promo_function (promo_category)) 
         * 
ERROR at line 2: 
ORA-00904: : invalid identifier 

SQL> 

유효하지 않은 식별자가 함수 이름을 나타냅니다. 왜? 스키마 B는 인덱스 스키마를 소유하지만 APC는 테이블을 소유하므로 함수도 실행할 수 있어야합니다. 이 솔루션은 테이블 소유자에 대한 기능을 실행 권한을 부여하는 것입니다 : 우리가 명시 적으로 기능 소유자뿐만 아니라이 문에서 테이블 소유자를 참조해야

SQL> conn b/b 
Connected. 
SQL> grant execute on promo_function to APC; 

Grant succeeded. 

SQL> CREATE INDEX promotions_fbi 
    2 ON APC.PROMOTIONS (B.promo_function (promo_category)); 
Index created. 

SQL> 

참고. 조금 더러운 점이 있습니다. 따라서이 방식으로 두 스키마에 걸쳐 권한을 분산시키는 것은 일반적으로 바람직하지 않습니다.


나는 확실히 기능 기반의 이름에 단어 기능을 사용하여 인덱스에 만들 수 @zaratustra는, 자신의 연구 결과를 얻는 방법 확실하지 ...

SQL> r 
    1 select i.table_owner, i.owner as index_owner, i.index_name 
    2   , i.index_type, e.column_expression 
    3 from all_indexes i 
    4  left join all_ind_expressions e 
    5   on i.owner = e.index_owner 
    6    and i.index_name = e.index_name 
    7* where i.table_name = 'PROMOTIONS' 

TABLE_OWNER     INDEX_OWNER 
------------------------------ ------------------------------ 
INDEX_NAME      INDEX_TYPE 
------------------------------ --------------------------- 
COLUMN_EXPRESSION 
-------------------------------------------------------------------------------- 
APC       APC 
PROMOTIONS_FBI     FUNCTION-BASED NORMAL 
"APC"."PROMO_FUNCTION"("PROMO_CATEGORY") 

APC       A 
PROMO_B_I      FUNCTION-BASED NORMAL 
"A"."B_FUNCTION"("PROMO_CATEGORY") 

APC       APC 
PROMOTIONS_I     NORMAL 



SQL> 

그게

SQL> select banner from v$version; 

BANNER 
-------------------------------------------------------------------------------- 
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - Production 

SQL> 
+0

로컬로 설치된 Oracle 서버가 없기 때문에 apex.oracle.com을 사용하여 작업을 수행했습니다. apex.oracle.com을 시도 할 수 있습니까? – zaratustra

+0

"해결책은 테이블 소유자에게 기능에 대한 실행 권한을 부여하는 것입니다."APC에 감사드립니다. 저는 개인 정보도 생각하고있었습니다. 이것은 매우 명확한 대답과 해결책입니다! – Thomas

0

오라클은 프로 시저 이름에 함수 단어를 사용하여 함수 기반 인덱스를 만들 수 없음을 알았습니다. 나를 위해 벌레처럼 보이는 :

CREATE OR REPLACE FUNCTION func_function(p_promo_category IN VARCHAR2) 
RETURN VARCHAR2 DETERMINISTIC IS 
BEGIN 
    RETURN UPPER(p_promo_category); 
END func_function; 

create table t1 (
    promo_category varchar2(4000) 
); 

Table created 

CREATE INDEX promotions_fbi ON t1 (func_function (promo_category)); 

ORA-00911: invalid character 

하는의는 이름에서 함수 단어없이 함수를 만들어 보자 :

CREATE OR REPLACE FUNCTION func_functio(p_promo_category IN VARCHAR2) 
RETURN VARCHAR2 DETERMINISTIC IS 
BEGIN 
    RETURN UPPER(p_promo_category); 
END func_functio; 

CREATE INDEX promotions_fbi ON t1 (func_functio (promo_category)); 

Index created 

select index_name, index_type 
    from user_indexes 
where lower(index_name) = 'promotions_fbi' 

INDEX_NAME  INDEX_TYPE 
------------------------------------- 
PROMOTIONS_FBI FUNCTION-BASED NORMAL 

내 Oracle 버전 :

select banner from v$version 

BANNER 
---------------------------------------------------------------------------- 
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production 
관련 문제