WEB开发网
开发学院数据库Oracle Oracle使用ANYDATA列对数据串行化方法 阅读

Oracle使用ANYDATA列对数据串行化方法

 2007-05-11 12:21:58 来源:WEB开发网   
核心提示: 一个ANYDATA对象可以通过使用任何Convert*方法构造简单值的方法来实现,或者通过“piecewise”构造方法创建诸如对象和数据库一类的更为复杂的变量,Oracle使用ANYDATA列对数据串行化方法(2),对于本例而言,我将集中解释如何使用Convert

一个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 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过程进行访问。

上一页  1 2 

Tags:Oracle 使用 ANYDATA

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接