专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »数据库 » 数据库的可串行化:Oracle使用ANYDATA列对数据串行化思路方法 »正文

数据库的可串行化:Oracle使用ANYDATA列对数据串行化思路方法

来源: 发布时间:星期二, 2009年1月13日 浏览:6次 评论:0
="t18"> Oracle版本9提供了种有趣数据类型开发人员借助此类型可以声明包括任何类型数据变量对于单个数据来说此数据类型即ANYDATA对于TABLE或者VARRAY数据来说则为ANYDATASETANYTYPE用于描述存储在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然后我将查询命令进行分解并描述从而得到个有关栏和数据类型列表再定义提取(fetch)出栏将每栏从各行中提取出来然后将其插入到串行化表格中在本例中我使用了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 eger not null,        item anydata      );      create or replace procedure serialize(p_tablename varchar2)      is        l_tablename varchar2(30) := upper(p_tablename);        c      pls_eger;    -- cursor        x      pls_eger;    -- dummy        col_cnt   pls_eger;        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._column(c,1,l_rowid,18);        for i in 2 .. col_cnt loop           dtab(i).col_type          when 1 then            dbms_sql._column(c,i,l_vc2,dtab(i).col_max_len);          when 2 then            dbms_sql._column(c,i,l_number);          when 9 then            dbms_sql._column(c,i,l_vc,dtab(i).col_max_len);          when 12 then            dbms_sql._column(c,i,l_date);          when 23 then            dbms_sql._column_raw(c,i,l_raw,dtab(i).col_max_len);          when 96 then            dbms_sql._column_char(c,i,l_ch,dtab(i).col_max_len);          when 112 then            dbms_sql._column(c,i,l_clob);          when 113 then            dbms_sql._column(c,i,l_blob);          when 114 then            dbms_sql._column(c,i,l_bfile);          end ;        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             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 ;            insert o 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过程进行访问

相关文章

读者评论

  • 共0条 分0页

发表评论

  • 昵称:
  • 内容: