2010-07-16 290 views
1

我可以讀取遊標中的列數據給出列的索引嗎?Oracle使用遊標讀取第n列

感謝...


從提問者的評論: 「我需要創建一個通用的過程,它會讀取表或視圖(視圖或表的名稱是PROC的說法)並加密列中的數據,然後將加密數據寫入OS文件。「

+0

你是什麼意思,像「從7選擇emp」獲得第7列?如果是的話答案是「否」。 – 2010-07-16 12:13:12

+0

不,有沒有像cursor.col_data(2)這樣的方法?其中2是第二列的索引。我不知道列的名稱,我怎麼讀? – mehmet6parmak 2010-07-16 12:15:31

+0

請給我們一個你的代碼的例子... – Tim 2010-07-16 12:19:33

回答

3

這應該會給你一個良好的開端。 只需插入您想要的列號的加密代碼即可。 我到處都使用了VARCHAR。如果你想要日期和數字(或更奇特的數據類型),那麼你需要處理轉換。

create or replace function qry_dump 
    (p_tab_name in varchar2, p_rownum in number default 5) 
return tab_char_4000 AUTHID CURRENT_USER pipelined is 
    v_line  varchar2(2000); 
    v_col_cnt INTEGER; 
    v_ind  NUMBER; 
    rec_tab  dbms_sql.desc_tab; 
    v_tab  dbms_sql.varchar2a; 
    v_temp  VARCHAR2(32000); 
    v_cursor NUMBER; 
    v_clause VARCHAR2(200); 
begin 
    -- 
    -- Initial values 
    -- v_ind := 1; 
    v_temp := 'select * from '||p_tab_name||' where rownum <= '||nvl(p_rownum,5); 
    -- 
    -- Identify the columns in the target and build the new query 
    -- 
    v_cursor := dbms_sql.open_cursor; 
    dbms_sql.parse(v_cursor, v_temp, dbms_sql.native); 
    dbms_sql.describe_columns(v_cursor, v_col_cnt, rec_tab); 
    -- 
    FOR v_pos in 1..rec_tab.LAST LOOP 
    v_line := rec_tab(v_pos).col_name; 
    dbms_sql.define_column(v_cursor, v_pos, v_line, 2000); 
    END LOOP; 
    v_ind := dbms_sql.execute(v_cursor); 
    -- 
    -- Fetch each row from the result set 
    -- 
    LOOP 
    v_ind := DBMS_SQL.FETCH_ROWS(v_cursor); 
    EXIT WHEN v_ind = 0; 
    pipe row('============================================================='); 
    -- 
    -- Go through each column and display it 
    -- 
    FOR v_col_seq IN 1 .. rec_tab.COUNT LOOP 
     -- Get the value 
     dbms_sql.column_value(v_cursor, v_col_seq, v_line); 
     pipe row(rpad(rec_tab(v_col_seq).col_name,35)||'>'||v_line); 
    END LOOP; 
    END LOOP; 
    return; 
end qry_dump; 
/

select * from table(qry_dump('DEPT',3)); 
+0

嗨,感謝您的回答,您的代碼與我的代碼非常相似。但是我有一個關於檢索數據大小的問題。我將列定義爲「',並給出了4096的長度。但是如果列是CLOB,該怎麼辦?我猜你的代碼在這一點上也爆發了。當我嘗試將columns_definition數據類型更改爲CLOB時,出現了一些錯誤,如「期望的數字有日期」有什麼想法? – mehmet6parmak 2010-07-19 07:07:21

1

CLOBs的附加答案。 更簡單的代碼,因爲我硬編碼了表/列名。 主要區別在於v_line現在是一個CLOB,並且最後一個參數(長度)從調用中刪除到DEFINE_COLUMN,因爲它只與VARCHAR2相關。

如果您在處理非常大的CLOB(例如10或100 MB以上),那麼我可以預見到其他挑戰(內存,性能......)。

create or replace function clob_dump 
return tab_char_4000 AUTHID CURRENT_USER pipelined is 
    v_line  clob; 
    v_col_cnt INTEGER; 
    v_ind  NUMBER; 
    rec_tab  dbms_sql.desc_tab; 
    v_cursor NUMBER; 
begin 
    -- 
    -- Identify the columns in the target and build the new query 
    -- 
    v_cursor := dbms_sql.open_cursor; 
    dbms_sql.parse(v_cursor, 'select sql_fulltext from gm_c where rownum <= 5', dbms_sql.native); 
    dbms_sql.describe_columns(v_cursor, v_col_cnt, rec_tab); 
    -- 
    FOR v_pos in 1..rec_tab.LAST LOOP 
    v_line := rec_tab(v_pos).col_name; 
    dbms_sql.define_column(v_cursor, v_pos, v_line); 
    END LOOP; 
    v_ind := dbms_sql.execute(v_cursor); 
    -- 
    -- Fetch each row from the result set 
    -- 
    LOOP 
    v_ind := DBMS_SQL.FETCH_ROWS(v_cursor); 
    EXIT WHEN v_ind = 0; 
    pipe row('============================================================='); 
    -- 
    -- Go through each column and display it 
    -- 
    FOR v_col_seq IN 1 .. rec_tab.COUNT LOOP 
     -- Get the value 
     dbms_sql.column_value(v_cursor, v_col_seq, v_line); 
     pipe row(rpad(rec_tab(v_col_seq).col_name,35)||'>'||substr(v_line,1,100)); 
    END LOOP; 
    END LOOP; 
    return; 
end clob_dump; 
/

select * from table(clob_dump);