我寫的測驗代碼如下:
CREATE TABLE testlkkj AS SELECT * FROM All_Tables;
SELECT * FROM testlkkj WHERE table_name = 'MGMT_PDP_METADATA';
CREATE OR REPLACE PROCEDURE proc_test001
AS
sql_tx VARCHAR2(3000);
tb_name VARCHAR2(200) := 'MGMT_PDP_METADATA';
BEGIN
sql_tx := --'delete from testlkkj where table_name = :v1';
'insert into testlkkj select * from all_tables where table_name = :v2';
EXECUTE IMMEDIATE sql_tx USING tb_name;
IF SQL%NOTFOUND OR SQL%NOTFOUND IS NULL
THEN dbms_output.put_line('沒有陳述句被執行');
END IF;
COMMIT;
END proc_test001;
BEGIN
proc_test001;
END;
預想中,執行之后testlkkj表中會新增一條記錄,但執行后,列印出“沒有陳述句被執行”,查看testlkkj表中的記錄,確實沒有新增。但當將sql_tx變成上面注釋掉的delete陳述句后,執行后testlkkj確實洗掉了一條資料。
求問,這個存盤程序中究竟存在什么問題,使insert陳述句未能成功執行但delete陳述句又能正常執行。
uj5u.com熱心網友回復:
insert into testlkkj .....是不是少個關鍵字values
uj5u.com熱心網友回復:
不是~ insert into tb1 select * from tb2 這個不需要values啊uj5u.com熱心網友回復:
動態sql的權限相關問題,我在我本地測驗了你的sql,因為你執行這個存盤程序的用戶,沒有查詢 MGMT_PDP_METADATA 這張表的權限。 我再本地授權了一下,執行,就有記錄了。uj5u.com熱心網友回復:
sql_tx := 'insert into testlkkj select * from all_tables where table_name ='''||:v2||''';:v2是傳入變數么? 需要放外面,你可以把動態執行陳述句列印出來看看到底執行的什么陳述句。
uj5u.com熱心網友回復:
sql_tx := 'insert into testlkkj select * from all_tables where table_name ='||:v2;uj5u.com熱心網友回復:
動態陳述句訪問 all_objects 類物件時,必須顯式的授權;uj5u.com熱心網友回復:
我在相同的用戶下,執行如下陳述句:DECLARE tb_name VARCHAR(20) := 'MGMT_PDP_METADATA';
sql_tx VARCHAR2(1000);
BEGIN
sql_tx := 'insert into testlkkj select * from all_tables where table_name = :1';
--EXECUTE IMMEDIATE 'insert into testlkkj select * from all_tables where table_name = :1' USING tb_name;
EXECUTE IMMEDIATE sql_tx USING tb_name;
IF SQL%NOTFOUND OR SQL%NOTFOUND IS NULL THEN
dbms_output.put_line('沒有陳述句被執行');
END IF;
COMMIT;
END;
能夠成功執行的啊。 同樣都是動態sql ,一個是存盤程序 一個不是,就會產生這樣的差別嗎
uj5u.com熱心網友回復:
--在10G測驗了一下,沒問題SQL> select * from testlkkj;
未選定行
SQL> CREATE OR REPLACE PROCEDURE proc_test001
2 AS
3 sql_tx VARCHAR2(3000);
4 tb_name VARCHAR2(200) := 'EMP';
5 BEGIN
6 sql_tx := --'delete from testlkkj where table_name = :v1';
7 'insert into testlkkj select * from all_tables where table_name = :v2';
8 EXECUTE IMMEDIATE sql_tx USING tb_name;
9 IF SQL%NOTFOUND OR SQL%NOTFOUND IS NULL
10 THEN dbms_output.put_line('沒有陳述句被執行');
11 END IF;
12 COMMIT;
13 END proc_test001;
14 /
程序已創建。
SQL> select * from testlkkj;
未選定行
SQL> BEGIN
2 proc_test001;
3 END;
4 /
PL/SQL 程序已成功完成。
SQL> select * from testlkkj;
OWNER TABLE_NAME TABLESPACE_NAME CLUSTER_NAME
------------------------------ ------------------------------ ------------------------------ -------------
SCOTT EMP SYCH_NEW
uj5u.com熱心網友回復:
對的,是有這樣的差別;
uj5u.com熱心網友回復:
樓主,編譯一下你的存盤程序能不能通過先。或者能不能試試將
END proc_test001;
改成
END;
/
uj5u.com熱心網友回復:
他是動態的 SQL ,如果沒有其他語法問題,是可以編譯通過的, 如果把這個 insert 陳述句拿出來,極有可能編譯不過去。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/112121.html
標籤:開發
上一篇:oracle問題,求教
