为什么我在尝试使用立即执行创建目录对象时收到 ORA-00900 Invalid SQL statement?
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;
我更喜欢将命令放入变量中,显示它(用于验证)然后执行它:
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>
当然,你必须运行它作为特权用户(例如SYS)。
这似乎是一个错误;虽然没有在关于 MoS 的 ORA-00900 参考说明中列出。
它不喜欢将路径变量连接为 execute immediate
的一部分。这失败了:
v_path := '/some/path';
execute immediate 'CREATE OR REPLACE DIRECTORY DIAG_TRACE AS ''' || v_path || '''';
但这没关系,即使最终声明是相同的:
execute immediate 'CREATE OR REPLACE DIRECTORY DIAG_TRACE AS ''/some/path''';
经过一番搜索,可能与bug 7036176有关:"CONCATENATED DYNAMIC OBJECT NAME RAISES ORA-00900 IN 10G & 11G"。它不完全相同但很接近。您需要查看 My Oracle Support 以获取更多信息,尽管信息不多。
您可以使用变量来解决它:
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;
/
这节省了重复打印字符串的时间,尽管您可能只是因为这个问题才这样做。
顺便说一句,不确定为什么要先放弃 or replace
。
我在 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;
我更喜欢将命令放入变量中,显示它(用于验证)然后执行它:
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>
当然,你必须运行它作为特权用户(例如SYS)。
这似乎是一个错误;虽然没有在关于 MoS 的 ORA-00900 参考说明中列出。
它不喜欢将路径变量连接为 execute immediate
的一部分。这失败了:
v_path := '/some/path';
execute immediate 'CREATE OR REPLACE DIRECTORY DIAG_TRACE AS ''' || v_path || '''';
但这没关系,即使最终声明是相同的:
execute immediate 'CREATE OR REPLACE DIRECTORY DIAG_TRACE AS ''/some/path''';
经过一番搜索,可能与bug 7036176有关:"CONCATENATED DYNAMIC OBJECT NAME RAISES ORA-00900 IN 10G & 11G"。它不完全相同但很接近。您需要查看 My Oracle Support 以获取更多信息,尽管信息不多。
您可以使用变量来解决它:
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;
/
这节省了重复打印字符串的时间,尽管您可能只是因为这个问题才这样做。
顺便说一句,不确定为什么要先放弃 or replace
。