즉시 실행으로 디렉토리 객체를 생성하려고 할 때 ORA-00900 Invalid SQL 문을 받는 이유는 무엇입니까? (Why am I getting ORA-00900 Invalid SQL statement when trying to create a directory object with execute immediate?)


문제 설명

즉시 실행으로 디렉토리 객체를 생성하려고 할 때 ORA‑00900 Invalid SQL 문을 받는 이유는 무엇입니까? (Why am I getting ORA‑00900 Invalid SQL statement when trying to create a directory object with execute immediate?)

저는 Oracle에서 이것이 가능한 많은 예를 봅니다. 그것은 나를 위해 작동하지 않습니다. Oracle 11. 15행에서 이 오류가 발생합니다. 모두 감사합니다!

declare 
v_path nvarchar2(256);
v_object_exists number;
begin
    ‑‑ Use the directory Oracle DB provide for tracing.
    select VALUE into v_path from V$DIAG_INFO where NAME = 'Diag Trace';
    ‑‑dbms_output.put_line(v_path);

    ‑‑ Set up new directory!
    select count(*) into v_object_exists from all_objects where object_name = 'DIAG_TRACE' and object_type = 'DIRECTORY';
    if v_object_exists > 0 then 
        execute immediate 'DROP DIRECTORY DIAG_TRACE'; 
    end if;
    dbms_output.put_line('CREATE OR REPLACE DIRECTORY DIAG_TRACE AS ''' || v_path || '''');
    execute immediate 'CREATE OR REPLACE DIRECTORY DIAG_TRACE AS ''' || v_path || '''';

end;

참조 솔루션

방법 1:

This appears to be a bug; though not one listed on the ORA‑00900 reference note on MoS.

It doesn't like the path variable being concatenated in as part of the execute immediate. This fails:

v_path := '/some/path';
execute immediate 'CREATE OR REPLACE DIRECTORY DIAG_TRACE AS ''' || v_path || '''';

but this is OK, even though the final statement is the same:

execute immediate 'CREATE OR REPLACE DIRECTORY DIAG_TRACE AS ''/some/path''';

After some searching, it may be something to do with bug 7036176: "CONCATENATED DYNAMIC OBJECT NAME RAISES ORA‑00900 IN 10G & 11G". It's not exactly the same but close. You'll need to look on My Oracle Support for further info, though there isn't much.

You can work around it with a variable:

declare
v_stmt varchar2(256);
v_path nvarchar2(256);
v_object_exists number;
begin
    ‑‑ Use the directory Oracle DB provide for tracing.
    select VALUE into v_path from V$DIAG_INFO where NAME = 'Diag Trace';
    ‑‑dbms_output.put_line(v_path);
    ‑‑ Set up new directory!
    select count(*) into v_object_exists from all_objects where object_name = 'DIAG_TRACE' and object_type = 'DIRECTORY';
    if v_object_exists > 0 then
        execute immediate 'DROP DIRECTORY DIAG_TRACE';
    end if;
    v_stmt := 'CREATE OR REPLACE DIRECTORY DIAG_TRACE AS ''' || v_path || '''';
    dbms_output.put_line(v_stmt);
    execute immediate v_stmt;
end;
/

Which saves repeating the string to print it, though you might only have done that because of this issue.

Not sure why you're dropping first with or replace, incidentally.

방법 2:

I prefer putting a command into a variable, display it (for verification) and then execute it:

SQL> declare
  2  v_path nvarchar2(256);
  3  v_object_exists number;
  4  l_str varchar2(200);
  5  begin
  6      ‑‑ Use the directory Oracle DB provide for tracing.
  7      select VALUE into v_path from V$DIAG_INFO where NAME = 'Diag Trace';
  8      ‑‑dbms_output.put_line(v_path);
  9
 10      ‑‑ Set up new directory!
 11      select count(*) into v_object_exists from all_objects where object_name = 'DIAG_TRACE' and object_type = 'DIRECTORY';
 12      if v_object_exists > 0 then
 13          execute immediate 'DROP DIRECTORY DIAG_TRACE';
 14      end if;
 15      l_str := 'CREATE OR REPLACE DIRECTORY DIAG_TRACE AS ' || chr(39) || v_path ||chr(39);
 16      dbms_output.put_line(l_str);
 17      execute immediate l_str;
 18  end;
 19  /
CREATE OR REPLACE DIRECTORY DIAG_TRACE AS
'C:\ORACLEXE\APP\ORACLE\diag\rdbms\xe\xe\trace'

PL/SQL procedure successfully completed.

SQL>

Certainly, you have to run it as a privileged user (such as SYS).

(by soisAlex PooleLittlefoot)

참조 문서

  1. Why am I getting ORA‑00900 Invalid SQL statement when trying to create a directory object with execute immediate? (CC BY‑SA 2.5/3.0/4.0)

#DDL #oracle #execute-immediate






관련 질문

비밀번호로 식별되지 않는 mysql 부여 권한 (mysql grant privileges without identified by password)

PL/SQL 블록의 문자열 변수에서 사용자 생성 (Create user from string variables in a PL/SQL block)

dbms_metadata.get_ddl을 더 예쁘고 유용하게 만드는 방법 (How to make dbms_metadata.get_ddl more pretty/useful)

Postgres에서 테이블의 모든 인덱스를 삭제하려면 어떻게 해야 합니까? (How can I drop all indexes of a table in Postgres?)

DB2의 카탈로그에서 "처음에 기록되지 않은" 테이블을 식별하는 방법 (How to identify tables with "not logged initially" from catalog in DB2)

blob 및 clob 데이터 유형이 있는 oracle11g에 테이블을 생성한 다음 다음 쿼리를 실행했습니다. (I have create table in oracle11g which has blob and clob data type and then I have run following query)

PL/pgsql DDL을 작성하여 redshift에서 스키마를 생성한 다음 ddls를 반복하여 각 스키마에 테이블을 생성하는 방법은 무엇입니까? (How to write PL/pgsql DDL to create schemas in redshift and then looping the ddls to create tables in the respective schemas?)

즉시 실행으로 디렉토리 객체를 생성하려고 할 때 ORA-00900 Invalid SQL 문을 받는 이유는 무엇입니까? (Why am I getting ORA-00900 Invalid SQL statement when trying to create a directory object with execute immediate?)

SQLAlchemy: 부분적으로 지정된 관계 (SQLAlchemy: partially specified relationship)

T-SQL의 한 스크립트에서 동일한 열 정의로 두 개의 테이블을 만드는 방법은 무엇입니까? (How to create two tables with same column definition in one script in T-SQL?)

지리 데이터 유형에서 네이티브 함수 반환 (Native Function Return from Geography Data Type)

Oracle - 커서를 기반으로 테이블 삭제를 위한 동적 함수 생성 (Oracle- creating dynamic function for deleting tables based on cursor)







코멘트