国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > Oracle > 正文

Oracle使用ANYDATA列對數據串行化方法

2024-08-29 13:50:45
字體:
來源:轉載
供稿:網友
Oracle版本9提供了一種有趣的新的數據類型,開發人員借助此類型可以聲明包括任何類型數據的變量。對于單個數據來說,此數據類型即ANYDATA。對于TABLE或者VARRAY數據來說,則為ANYDATASET。ANYTYPE用于描述存儲在ANYDATA或者ANYDATASET變量以及欄中的數據類型。這些數據類型對于處理存儲在數據庫中的xml數據或高級序列(Advanced Queues)具有非常重要的意義。說明文檔中提到了ANYDATA數據類型可以用于對對象進行串行化(serialize),但與之相關的示例較少。 串行化首先將數據值和其他結構(strUCture)組成為另外一些結構,然后將生成的結構的所有構成成分輸出為流。流可以被結構返回讀取,并且將覆蓋前一個會話的信息。通常而言,在應用程序中進行的保存和打開文件的操作即不過是串行化的一種形式。 一個Oracle數據庫或許需要使用串行化功能來存儲一些表格數據的某個版本備份,這樣可以在不使用數據庫提交(commits)、回滾(rollbacks)、回閃(Flashback)查詢的情況下對數據進行查看和其他操作。許多應用程序都會用到類似的對數據源的控制功能,諸如可以在應用級對當前和以前的數據版本進行比較,或對合并操作(merge)和撤銷操作(undo)所產生數據改變進行比較。很多此類應用程序都被設計為對每個表格創建一個備份表格。而對于數據庫性能和開發進度來說,要維護這些眾多的備份表格以及之間的各種關系,成為了生產數據(PRoduction data)以外的沉重負擔。 而通過ANYDATA數據類型以及動態SQL功能,使得通過單一的串行化存儲進程來把許多需要備份的表格串行輸入到一個單獨的備份表格成為可能。ANYDATA的一個優勢在于,不同于類似VARCHAR2的簡單的轉換數據類型,使用ANYDATA方法原始的數據類型并不會丟失。數據可以被存儲在ANYDATA欄或者變量中而不會丟失任何細節(或根據在DATA和VARCHAR2之間進行轉換的當前NLS語義而定)。這些存儲的數據在轉化過程中不會有任何損失。 一個ANYDATA對象可以通過使用任何Convert*方法構造簡單值的方法來實現,或者通過“piecewise”構造方法創建諸如對象和數據庫一類的更為復雜的變量。對于本例而言,我將集中解釋如何使用Convert*方法。 為了創建一個串行化進程,我使用了動態SQL來產生一個對表格中所有數據的查詢命令,其中包括ROWID。然后我將查詢命令進行分解并描述,從而得到一個關于欄和數據類型的列表。再定義提?。╢etch)出欄,將每一欄從各行中提取出來,然后將其插入到串行化表格中。在本例中我使用了DBMS_SQL,因為“自身動態SQL(native dynamic SQL)”現在還不能支持描述動態查詢。絕大多數的工作都是對從DBMS_SQL數據類型代碼到合適的數據類型方法以及函數的轉換過程進行處理。要得到這些代碼的列表,可以查看OCI包含文件ocidfn.h,或者是諸如USER_TAB_COLUMNS這樣的對查看(view)的定義。在本例中,我使用了簡單的數據類型(可以在EMP和DEPT表格中找到),這樣可以直接對其進行轉換。
    drop table serialized_data;    create table serialized_data    (      tablename varchar2(30) not null,      row_id rowid not null,      colseq integer not null,      item anydata    );    create or replace procedure serialize(p_tablename varchar2)    is      l_tablename varchar2(30) := upper(p_tablename);      c      pls_integer;    -- cursor      x      pls_integer;    -- dummy      col_cnt   pls_integer;      dtab    dbms_sql.desc_tab;      l_rowid   char(18);      l_anydata  anydata;      l_vc2    varchar2(32767);      l_number  number;      l_vc    varchar(32767);      l_date   date;      l_raw    raw(32767);      l_ch    char;      l_clob   clob;      l_blob   blob;      l_bfile   bfile;    begin      c := dbms_sql.open_cursor;      dbms_sql.parse(c,'select rowid,'p_tablename'.* from 'p_tablename,        dbms_sql.native);      dbms_sql.describe_columns(c,col_cnt,dtab);      dbms_sql.define_column(c,1,l_rowid,18);      for i in 2 .. col_cnt loop        case dtab(i).col_type        when 1 then          dbms_sql.define_column(c,i,l_vc2,dtab(i).col_max_len);        when 2 then          dbms_sql.define_column(c,i,l_number);        when 9 then          dbms_sql.define_column(c,i,l_vc,dtab(i).col_max_len);        when 12 then          dbms_sql.define_column(c,i,l_date);        when 23 then          dbms_sql.define_column_raw(c,i,l_raw,dtab(i).col_max_len);        when 96 then          dbms_sql.define_column_char(c,i,l_ch,dtab(i).col_max_len);        when 112 then          dbms_sql.define_column(c,i,l_clob);        when 113 then          dbms_sql.define_column(c,i,l_blob);        when 114 then          dbms_sql.define_column(c,i,l_bfile);        end case;      end loop;      x := dbms_sql.execute(c);      while dbms_sql.fetch_rows(c) != 0 loop        dbms_sql.column_value(c,1,l_rowid);        for i in 2 .. col_cnt loop          case dtab(i).col_type          when 1 then            dbms_sql.column_value(c,i,l_vc2);            l_anydata := ANYDATA.ConvertVarchar2(l_vc2);          when 2 then            dbms_sql.column_value(c,i,l_number);            l_anydata := ANYDATA.ConvertNumber(l_number);          when 9 then            dbms_sql.column_value(c,i,l_vc);            l_anydata := ANYDATA.ConvertVarchar(l_vc);          when 12 then            dbms_sql.column_value(c,i,l_date);            l_anydata := ANYDATA.ConvertDate(l_date);          when 23 then            dbms_sql.column_value(c,i,l_raw);            l_anydata := ANYDATA.ConvertRaw(l_raw);          when 96 then            dbms_sql.column_value(c,i,l_ch);            l_anydata := ANYDATA.ConvertChar(l_ch);          when 112 then            dbms_sql.column_value(c,i,l_clob);            l_anydata := ANYDATA.ConvertClob(l_clob);          when 113 then            dbms_sql.column_value(c,i,l_blob);            l_anydata := ANYDATA.ConvertBlob(l_blob);          when 114 then            dbms_sql.column_value(c,i,l_bfile);            l_anydata := ANYDATA.ConvertBFile(l_bfile);          end case;          insert into serialized_data (tablename,row_id,colseq,item)            values (l_tablename,l_rowid,i,l_anydata);        end loop;      end loop;      dbms_sql.close_cursor(c);    end;    /    show errors;
   假如我希望對“EMP”和“DEPT”表格串行化,我可以按照以下代碼通過SQL*Plus來完成:
    exec serialize('emp');    exec serialize('dept');    select t.item.gettypename() from serialized_data t;
   使用ANYDATA中的一個問題是,假如是對象,則只有很少的信息可以通過直接SQL恢復過來。表格數據必須使用PL/SQL過程進行訪問。


上一篇:關于Oracle服務器性能全面調整攻略

下一篇:Oracle 9i輕松取得建表和索引DDL語句

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

主站蜘蛛池模板: 台湾省| 阜城县| 庆安县| 东港市| 青冈县| 河池市| 长沙市| 郯城县| 宜川县| 万州区| 永安市| 远安县| 镇安县| 和平区| 区。| 长宁县| 沁水县| 达日县| 林芝县| 永顺县| 井冈山市| 蒙城县| 长岭县| 葫芦岛市| 三穗县| 淄博市| 岑溪市| 大安市| 洛宁县| 东兰县| 宜川县| 石柱| 集安市| 灯塔市| 嘉祥县| 城步| 潞西市| 崇仁县| 黑水县| 盐山县| 宁津县|