EXECUTE IMMEDIATE DROP FUNCTION 导致 Oracle SQL Developer 挂起
EXECUTE IMMEDIATE DROP FUNCTION causes Oracle SQL Developer to hang
我有以下脚本。但是每当我包含 EXECUTE IMMEDIATE 'DROP FUNCTION table_exists';
行时,SQL 开发人员似乎挂起。知道是什么原因造成的吗?
如果我取消任务,脚本 运行 会完成但不会删除该功能。但是,我可以简单地 运行 DROP FUNCTION table_exists;
在我的数据库连接中,它会丢弃 table 没问题。是 PL/SQL 的怪癖吗?
CREATE OR REPLACE FUNCTION table_exists(table_name VARCHAR2)
RETURN BOOLEAN
AS
table_count NUMBER := 0;
exists_sql VARCHAR2(255);
BEGIN
exists_sql := 'SELECT COUNT(1) FROM tab WHERE tname = :tab_name';
EXECUTE IMMEDIATE exists_sql INTO table_count USING table_name;
RETURN table_count > 0;
END;
/
DECLARE
TYPE tables_array IS VARRAY(2) OF VARCHAR2(25); -- change varray size if running on dev
tables tables_array;
BEGIN
tables := tables_array(
'FOO',
'BAR'
);
FOR table_element IN 1 .. tables.COUNT LOOP
DBMS_OUTPUT.PUT_LINE('Backing up data for ' || tables(table_element));
IF table_exists(tables(table_element) || '_ORIGINAL') THEN
DBMS_OUTPUT.PUT_LINE(tables(table_element) || '_ORIGINAL already exists');
ELSE
EXECUTE IMMEDIATE 'CREATE TABLE ' || tables(table_element) || '_ORIGINAL AS SELECT * FROM '|| tables(table_element);
END IF;
END LOOP;
EXECUTE IMMEDIATE 'DROP FUNCTION table_exists';
COMMIT;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE ('Unexpected error: ' || sqlerrm);
ROLLBACK;
RAISE;
END;
/
Oracle 不会删除在此过程中使用的函数。
有解决办法吗?是的,至少一个 - 提交一个将在另一个会话中完成的作业。
示例表(这样程序就不会因此失败)
SQL> create table foo (id number);
Table created.
SQL> create table bar (id number);
Table created.
创建函数:
SQL> CREATE OR REPLACE FUNCTION table_exists(table_name VARCHAR2)
2 RETURN BOOLEAN
3 AS
4 table_count NUMBER := 0;
5 exists_sql VARCHAR2(255);
6 BEGIN
7 exists_sql := 'SELECT COUNT(1) FROM tab WHERE tname = :tab_name';
8 EXECUTE IMMEDIATE exists_sql INTO table_count USING table_name;
9
10 RETURN table_count > 0;
11 END;
12 /
Function created.
在吗?是的,它是:
SQL> desc table_Exists;
FUNCTION table_Exists RETURNS BOOLEAN
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
TABLE_NAME VARCHAR2 IN
运行主要代码段;请注意 line #4(包含作业编号的变量声明)和 line #21 提交作业。
SQL> DECLARE
2 TYPE tables_array IS VARRAY(2) OF VARCHAR2(25); -- change varray size if running on dev
3 tables tables_array;
4 i number; -- job number
5 BEGIN
6 tables := tables_array(
7 'FOO',
8 'BAR'
9 );
10
11 FOR table_element IN 1 .. tables.COUNT LOOP
12 DBMS_OUTPUT.PUT_LINE('Backing up data for ' || tables(table_element));
13 IF table_exists(tables(table_element) || '_ORIGINAL') THEN
14 DBMS_OUTPUT.PUT_LINE(tables(table_element) || '_ORIGINAL already exists');
15 ELSE
16 EXECUTE IMMEDIATE 'CREATE TABLE ' || tables(table_element) || '_ORIGINAL AS SELECT * FROM '|| tables(table_element);
17 END IF;
18 END LOOP;
19
20 -- EXECUTE IMMEDIATE 'DROP FUNCTION table_exists';
21 dbms_job.submit(i, 'begin execute immediate ''drop function table_exists''; end;');
22
23 COMMIT;
24
25 EXCEPTION
26 WHEN OTHERS THEN
27 DBMS_OUTPUT.PUT_LINE ('Unexpected error: ' || sqlerrm);
28 ROLLBACK;
29 RAISE;
30 END;
31 /
PL/SQL procedure successfully completed.
这个功能还在吗?不,它被丢弃了。
SQL> desc table_exists;
ERROR:
ORA-04043: object table_exists does not exist
SQL>
我有以下脚本。但是每当我包含 EXECUTE IMMEDIATE 'DROP FUNCTION table_exists';
行时,SQL 开发人员似乎挂起。知道是什么原因造成的吗?
如果我取消任务,脚本 运行 会完成但不会删除该功能。但是,我可以简单地 运行 DROP FUNCTION table_exists;
在我的数据库连接中,它会丢弃 table 没问题。是 PL/SQL 的怪癖吗?
CREATE OR REPLACE FUNCTION table_exists(table_name VARCHAR2)
RETURN BOOLEAN
AS
table_count NUMBER := 0;
exists_sql VARCHAR2(255);
BEGIN
exists_sql := 'SELECT COUNT(1) FROM tab WHERE tname = :tab_name';
EXECUTE IMMEDIATE exists_sql INTO table_count USING table_name;
RETURN table_count > 0;
END;
/
DECLARE
TYPE tables_array IS VARRAY(2) OF VARCHAR2(25); -- change varray size if running on dev
tables tables_array;
BEGIN
tables := tables_array(
'FOO',
'BAR'
);
FOR table_element IN 1 .. tables.COUNT LOOP
DBMS_OUTPUT.PUT_LINE('Backing up data for ' || tables(table_element));
IF table_exists(tables(table_element) || '_ORIGINAL') THEN
DBMS_OUTPUT.PUT_LINE(tables(table_element) || '_ORIGINAL already exists');
ELSE
EXECUTE IMMEDIATE 'CREATE TABLE ' || tables(table_element) || '_ORIGINAL AS SELECT * FROM '|| tables(table_element);
END IF;
END LOOP;
EXECUTE IMMEDIATE 'DROP FUNCTION table_exists';
COMMIT;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE ('Unexpected error: ' || sqlerrm);
ROLLBACK;
RAISE;
END;
/
Oracle 不会删除在此过程中使用的函数。
有解决办法吗?是的,至少一个 - 提交一个将在另一个会话中完成的作业。
示例表(这样程序就不会因此失败)
SQL> create table foo (id number);
Table created.
SQL> create table bar (id number);
Table created.
创建函数:
SQL> CREATE OR REPLACE FUNCTION table_exists(table_name VARCHAR2)
2 RETURN BOOLEAN
3 AS
4 table_count NUMBER := 0;
5 exists_sql VARCHAR2(255);
6 BEGIN
7 exists_sql := 'SELECT COUNT(1) FROM tab WHERE tname = :tab_name';
8 EXECUTE IMMEDIATE exists_sql INTO table_count USING table_name;
9
10 RETURN table_count > 0;
11 END;
12 /
Function created.
在吗?是的,它是:
SQL> desc table_Exists;
FUNCTION table_Exists RETURNS BOOLEAN
Argument Name Type In/Out Default?
------------------------------ ----------------------- ------ --------
TABLE_NAME VARCHAR2 IN
运行主要代码段;请注意 line #4(包含作业编号的变量声明)和 line #21 提交作业。
SQL> DECLARE
2 TYPE tables_array IS VARRAY(2) OF VARCHAR2(25); -- change varray size if running on dev
3 tables tables_array;
4 i number; -- job number
5 BEGIN
6 tables := tables_array(
7 'FOO',
8 'BAR'
9 );
10
11 FOR table_element IN 1 .. tables.COUNT LOOP
12 DBMS_OUTPUT.PUT_LINE('Backing up data for ' || tables(table_element));
13 IF table_exists(tables(table_element) || '_ORIGINAL') THEN
14 DBMS_OUTPUT.PUT_LINE(tables(table_element) || '_ORIGINAL already exists');
15 ELSE
16 EXECUTE IMMEDIATE 'CREATE TABLE ' || tables(table_element) || '_ORIGINAL AS SELECT * FROM '|| tables(table_element);
17 END IF;
18 END LOOP;
19
20 -- EXECUTE IMMEDIATE 'DROP FUNCTION table_exists';
21 dbms_job.submit(i, 'begin execute immediate ''drop function table_exists''; end;');
22
23 COMMIT;
24
25 EXCEPTION
26 WHEN OTHERS THEN
27 DBMS_OUTPUT.PUT_LINE ('Unexpected error: ' || sqlerrm);
28 ROLLBACK;
29 RAISE;
30 END;
31 /
PL/SQL procedure successfully completed.
这个功能还在吗?不,它被丢弃了。
SQL> desc table_exists;
ERROR:
ORA-04043: object table_exists does not exist
SQL>