2012-10-19 25 views
0

我想讓用戶輸入一個變量並將其用於遊標。該用戶輸入說明要使用哪個數據庫。獲取架構名稱作爲用戶輸入並在遊標中使用它

--source source 
source varchar2(100) := &SOURCE_ATS_USER_SCHEMA; 
CURSOR cur_list is 
    select ID from source.WEB_FE; 

我在DECLARE塊中使用上面的代碼。當這運行時,提示會詢問用戶輸入。 假設我輸入爲「ONE」,那麼它給出錯誤「標識符ONE必須聲明」,儘管ONE.WEB_FE表存在它說「表或視圖不存在」。

那麼如何將模式名稱作爲用戶輸入並在遊標中使用?

感謝名單

回答

0

您在這裏有兩個問題。消息identifier ONE must be declared是因爲你沒有引用替換變量。如果你有set verify on那麼你會看到類似這樣的:

Enter value for source_ats_user_schema: ONE 
old 2: source varchar2(100) := &SOURCE_ATS_USER_SCHEMA; 
new 2: source varchar2(100) := ONE; 
source varchar2(100) := ONE; 
         * 
ERROR at line 2: 
ORA-06550: line 2, column 25: 
PLS-00201: identifier 'SCOTT' must be declared 
ORA-06550: line 2, column 8: 
PL/SQL: Item ignored 

*「d立場表明,它不知道什麼ONE手段。既然你想讓它在這裏視爲一個字符串,你需要做的:

source varchar2(100) := '&SOURCE_ATS_USER_SCHEMA'; 

...這將顯示:

Enter value for source_ats_user_schema: ONE 
old 2: source varchar2(100) := '&SOURCE_ATS_USER_SCHEMA'; 
new 2: source varchar2(100) := 'ONE'; 

...這是有效的。就它而言;這並不能真正幫助你,因爲你還有第二個錯誤:

select ID from source.WEB_FE; 
          * 
ERROR at line 4: 
ORA-06550: line 4, column 27: 
PL/SQL: ORA-00942: table or view does not exist 
ORA-06550: line 4, column 5: 
PL/SQL: SQL Statement ignored 

注意,錯誤指的是source.WEB_FEONE.WEB_FEsource未被替換。一般來說,你需要使用@NicholasKrasnov在他的答案中所展示的方法之一,但實際上這使得它比需要的更加複雜;在這種特殊情況下,你不需要申報source可言,你可以這樣做:

CURSOR cur_list is 
    select ID from &SOURCE_ATS_USER_SCHEMA..WEB_FE; 

注意,相反的是我剛纔說的,在這裏你不需要引用替代變量,但你需要使用.明確終止它,以阻止它在作爲終止符的表名之前處理真正的.。 (如果沒有,請在沒有額外的.的情況下嘗試看看會發生什麼情況)。

當你運行它,它會提示和驗證輸出如下:

Enter value for source_ats_user_schema: ONE 
old 3:  select ID from &SOURCE_ATS_USER_SCHEMA..WEB_FE; 
new 3:  select ID from ONE.WEB_FE; 

正如你所看到的,它現在正在尋找在您指定的架構表。這仍然是動態的,但採用特殊的SQL * Plus方式。

儘管有這些方法,但您需要考慮SQL注入的潛力。

+0

謝謝。 source varchar2(100):='&SOURCE_ATS_USER_SCHEMA';訣竅。 – saji159

1

假設你有select on權限查詢你沒有自己的表。爲了能夠更改查詢的from子句中的模式限定符,您需要使用動態SQL。例如:

[email protected]> edit 
Wrote file afiedt.buf 

    1 declare 
    2 c sys_refcursor; 
    3 l_emp_name varchar2(11); 
    4 begin 
    5 open c for 'select first_name from ' || '&schema_name' || '.employees where rownum <= 10'; 
    6 loop 
    7  fetch c into l_emp_name; 
    8  exit when c%notfound; 
    9  dbms_output.put_line(l_emp_name); 
10 end loop; 
11 close c; 
12* end; 
[email protected]>/
Enter value for schema_name: hr 
old 5: open c for 'select first_name from ' || '&schema_name' || '.employees where rownum <= 10'; 
new 5: open c for 'select first_name from ' || 'hr' || '.employees where rownum <= 10'; 

Ellen 
Sundar 
Mozhe 
David 
Hermann 
Shelli 
Amit 
Elizabeth 
Sarah 
David 

PL/SQL procedure successfully completed. 

[email protected]> 

您也可以繼續使用靜態SQL和改變模式在這種情況下,你不需要通過指定架構名稱來限定您所查詢的表發出

alter session set current_schema = <<schema_name>>; 

注意。例如。該employee表存在兩種模式HRNK但包含不同的數據:

[email protected]> select user from dual; 

USER 
------------------------------ 
HR 

[email protected]> declare 
    2 cursor c is 
    3  select first_name 
    4  from employees 
    5  where rownum <= 7; 
    6 l_emp_name varchar2(11); 
    7 begin 
    8  open c; 
    9  loop 
10  fetch c into l_emp_name; 
11  exit when c%notfound; 
12  dbms_output.put_line(l_emp_name); 
13  end loop; 
14  close c; 
15 end; 
16/

Ellen 
Sundar 
Mozhe 
David 
Hermann 
Shelli 
Amit 

PL/SQL procedure successfully completed. 

[email protected]> alter session set current_schema=NK; 

Session altered. 

[email protected]> declare 
    2 cursor c is 
    3  select first_name 
    4  from employees 
    5  where rownum <= 7; 
    6 l_emp_name varchar2(11); 
    7 begin 
    8  open c; 
    9  loop 
10  fetch c into l_emp_name; 
11  exit when c%notfound; 
12  dbms_output.put_line(l_emp_name); 
13  end loop; 
14  close c; 
15 end; 
16/

Tom 

PL/SQL procedure successfully completed. 

[email protected]> alter session set current_schema=HR; 

Session altered. 

[email protected]> 
+0

感謝您的支持。但是我不得不從另一個模式中引用四個表,並且我不能提示用戶輸入四次。正如Alex Poole所說,source varchar2(100):='&SOURCE_ATS_USER_SCHEMA';爲我工作。 – saji159

相關問題