2016-06-10 124 views
0

我想通過給2個變量作爲輸入來創建一個函數。這兩個變量在函數中動態使用。我在循環的開始部分使用select語句來查找特定表中的主鍵列。該列被分配給變量值1。我使用這個value1變量作爲序列變量。動態函數 - 甲骨文

create FUNCTION Test(schemaname in varchar2, tablename in varchar2) 
return number 
IS cnpParmId NUMBER; 
good VARCHAR(1) := 'F'; 
exist VARCHAR(1) := 'F'; 
value1 varchar2(500); 

begin 
good := 'F'; 
exist := 'F'; 
loop 
    SELECT cols.column_name into value1 
     FROM all_constraints cons, all_cons_columns cols 
     WHERE cols.TABLE_NAME= 'tablename' 
     And cols.OWNER='schemaname' 
     And cons.constraint_type = 'P' 
     AND cons.constraint_name = cols.constraint_name 
     AND cons.owner = cols.owner 
     ORDER BY cols.table_name, cols.position; 

    select schemaname.value1_seq.nextval into cnpParmId from dual; 
    begin 
     select 'T' into good from dual 
     where cnpParmId not in 
     (select value1 from schemaname.tablename); 
     exception when NO_DATA_FOUND then good := 'F'; 
    end; 
    exit when good = 'T'; 
end loop; 
return cnpParmId; 
end; 
/

Test(XYZ,ABC); 

但正在以下錯誤:

錯誤(21,11):PLS-00487:無效參照可變 'SCHEMANAME'

錯誤(21,22):PL/SQL:ORA-02289:序列不存在

錯誤(23,7):PL/SQL:SQL語句忽略

錯誤(25,38):PL/SQL:ORA-00942:表或查看不存在

回答

1

將變量引入表或列名稱時,需要使用EXECUTE IMMEDIATE進行動態查詢。

你的序列查詢應該是:

execute immediate 'select ' || schemaname || '.nextval from dual' into cnpParmId; 

和你「獲得返回值」查詢應該是:

execute immediate 
    'select ''T'' from dual where cnpParmId not in ' || 
    '(select value1 from ' || schemaname || '.' || tablename || ')' into good; 

另外請注意,您的查詢來獲取value1正在尋找字面 values schemaname and tablename

SELECT cols.column_name into value1 
    FROM all_constraints cons, all_cons_columns cols 
    WHERE cols.TABLE_NAME= 'tablename' 
    And cols.OWNER='schemaname' 
    ... and so on 

可以使用變量來表示的值,所以就擺脫了單引號周圍的變量名:

SELECT cols.column_name into value1 
    FROM all_constraints cons, all_cons_columns cols 
    WHERE cols.TABLE_NAME= tablename 
    And cols.OWNER=schemaname 
    ... and so on