oracle的包、用户数据类型与内存表的实现

原创 2007年10月12日 16:24:00

        最近在做的一个项目中,需要从UDP接收数据,数据记录了同样的点不同时间的值,然后每分钟定时将接收到的值更新到数据库中,但是接收数据的时间虽然在一分钟左右,但时间并不准确,如果UDP没有接收到数据,也必须将上次收到的数据再次提交给数据库,因此将接收数据和定时更新分开,接收数据和提交数据互不干涉。然而这么做问题来了,整个系统是建立在ORACLE库上的,而ORACLE是没有内存表的,如果在ORACLE中建表来保存数据,会对硬盘的频繁读写,时间长了容易出现硬盘坏道;如果在程序中保存,那么提交时必须采用循环整个数组,一次次地提交,效率上就会比较低。

       我考虑了两种方案,一种是采用在操作系统上建虚拟硬盘,然后再在虚盘上建立SQL server数据库,接收到的UDP数据直接发送到SQL server更新数据,然后再在ORACLE中建立一个从这个SQL server到ORACLE数据库的透明网关,定时从SQL server库中更新ORACLE库德数据。

        另外一种方法,就是使用包和用户数据类型来实现内存表,这样可以利用ORACLE本身的功能,而不用再去使用别的数据库服务,从效率上来说,也比较高。

        ORACLE库中表mytable结构为:

       MYINDEX                                            NUMBER
       SAVETIME                                           DATE
       MYVALUE                                            NUMBER

       首先,需要建立一个对象类型:

CREATE TYPE myobjtype AS OBJECT ( "MYINDEX " NUMBER, "MYNAME"  VARCHAR2(12), "MYVALUE" FLOAT     )

     然后根据这个对象类型来建立一个表类型:

CREATE TYPE mytabletype AS    TABLE OF myobjtype

    鉴于UDP接收时更新的需要,再建立一个对象类型用于更新:

CREATE TYPE mysetvalobjtype AS OBJECT ( "MYNAME" VARCHAR2(12),  "MYVALUE" FLOAT     )

然后建立一个程序包:

CREATE OR REPLACE  PACKAGE mytest is
 TESTNO mytabletype :=mytabletype ();
 Procedure setTESTNO(setval in mysetvalobjtype );
 Procedure ADDTESTNO(setval in myobjtype );
 function getTESTNO return mytabletype ;
end MYTEST;

建立包体:

CREATE OR REPLACE  PACKAGE BODY .""  is
 Procedure setTESTNO(setval in TESTNAMEVAL)
 is
   i number;
 begin
   for i in 1..TESTNO.count loop
     if TESTNO(i).MYNAME=setval.MYNAME then
       TESTNO(i).MYVALUE:=setval.MYVALUE;
     end if;
   end loop;
 end;
 
Procedure ADDTESTNO(setval in myobjtype )
 is
 begin
   TESTNO.extend;
   TESTNO(TESTNO.count):=setval;
 end;

  function getTESTNO return mytabletype 
 is
 begin
   return TESTNO;
 end;
end MYTEST;

        在这当中,TESTNO是保存数据的变量, ADDTESTNO是增加数据中成员的过程,setTESTNO是修改数据中成员的值的过程,getTESTNO是返回所有成员的函数,

       然后建一个程序来接收UDP(我使用的是C#),程序在开始向数据库写数据前要初始化,使用ADDTESTNO将变量的成员加进去,下面是初始化循环中的语句:

cmd.CommandText = "mytest.ADDTESTNO(TESTOBJTYPE(" + myindex.ToString() + ",/'" + myname + "/',0))";
cmd.ExecuteNonQuery();

其中myindex是循环中当前的数据对应的编号,myname 是当前的数据名称(UDP以它作为数据的标识)
然后是接收UDP数据后对变量成员的修改:

cmd.CommandText = "mytest.setTESTNO(TESTNAMEVAL(/'" +udpdataname + "/'," +udpdatavalue.ToString() + "))";
cmd.ExecuteNonQuery();
其中udpdataname 是从UDP中解析出来的名称,udpdatavalue是从UDP中解析出来的值。

最后就是每分钟定时修改数据了:

cmd.CommandText = "insert into testmemtable select MYINDEX,sysda,MYVALUE from table(mytest.gettestno)";
cmd.ExecuteNonQuery();

运行程序,程序就会定时将数据保存到数据库。

需要注意的是,写包变量和读包变量要在同一个程序,如果程序退出,变量TESTNO 中的内容也会被清掉,虽然在程序的生命周期中该变量可以当作全局的来使用,但是其它程序无法读取变量中的内容的。

oracle将A用户下的所有table,packe的权限赋予给B用户

1 表权限: 登录scott/tiger,然后查询select 'grant select on '||tname||' to robbie;' from tab tab表存储当前登录用户的所有表...
  • han_dongwei
  • han_dongwei
  • 2015-01-23 17:58:06
  • 5064

oracle10g中HR用户所有表的创建sql文件

  • 2010年04月17日 10:36
  • 18KB
  • 下载

Oracle 内存表的使用方法总结

Oracle 内存表的使用方法总结 http://www.itpub.net/forum.php?mod=viewthread&tid=1707128
  • orion61
  • orion61
  • 2013-01-24 17:08:51
  • 7476

使用CodeSmith生成oracle数据库表的实体层(Model)

自己写的,CodeSimth中的例子都是msSQL server的,所以自己写了个支持Oracle数据库表的,不一定很完善,适用就好,数据类型没有周全考虑,只考虑了常用的一些类型,增加了个表名字属性,...
  • dacong
  • dacong
  • 2009-01-27 16:28:00
  • 2970

Oracle查询用户所有的表、包、包体、过程、函数等信息

-- 查询所有用户的表,视图等 select * from all_tab_comments    -- 查询本用户的表,视图等 select * from user_tab_comment...
  • yixh1
  • yixh1
  • 2013-12-06 14:17:21
  • 691

借助内存表处理复杂的oracle查询要求

借助内存表处理复杂的oracle查询要求.在日常业务处理过程中,我们经常会碰到一些非常规的查询需求, 这些需求我们或者可以借助动态语句,或者其他现有的oracle函数完成查询结果, 但效率往往差强人意...
  • 47522341
  • 47522341
  • 2009-06-10 15:27:00
  • 9600

C#调用自定义表类型参数

C#调用自定义表类型参数
  • roy_88
  • roy_88
  • 2016-01-09 17:08:26
  • 3201

oracle中如何将表缓存到内存中

oracle中如何将表缓存到内存中   由于在一些静态资料表在数据库中被频繁的访问,所以可以考虑将这些数据量不大的表缓存到内存当中。   共有2种方法:   例:将fisher表缓存到内存...
  • libaolin198706231987
  • libaolin198706231987
  • 2015-12-14 11:05:41
  • 2500

PL/SQL表(oracle内存表)---table()函数用法

PL/SQL表(oracle内存表)---table()函数用法 http://blog.csdn.net/jojo52013145/article/details/6758279   Orac...
  • orion61
  • orion61
  • 2013-01-23 17:14:54
  • 1513

ORACLE中修改已存数据的列的数据类型

在Oralce中,修改一张表中数据列的类型,前提是该列不能有数据,否则无法修改,在plsql中会出现如下提示 为此,可以采用两种方式解决。 1、转移列数据后重命名的方式  --创建一个临时列...
  • u014727260
  • u014727260
  • 2016-12-06 18:43:06
  • 325
收藏助手
不良信息举报
您举报文章:oracle的包、用户数据类型与内存表的实现
举报原因:
原因补充:

(最多只允许输入30个字)